Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature : Possibility to change the source code folder #25

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

D4r1u5K
Copy link

@D4r1u5K D4r1u5K commented Sep 27, 2024

Actual Files Organisation and objectif

The actual organisation of the repo is the following

web/
  components/
  css/
  node_modules/
  layout.html.eex
  package.json
  webpack.config.js

This files and folders organisation merge config files with source folders. My intention is to be able to add a folder level for source code like this

web/
  src/
    components/
    css/
    layout.html.eex
  node_modules/
  package.json
  webpack.config.js

This way we can more clearly add comlexity in source code organisation with hooks, pages, utils, middleware and all other usefull folders for stronger file organisation.

The limitations

Today the "components" folder is locked at this place in the folder structure because it is hardcoded. Some workaround are kind of possible but i don't think that having a dependencies forcing a specific folder structure is a good thing.

The approch

The idea is quit simple, keep the hardcoded "components" folder to not bring breaking changes, but adding an option to change it. The impact on the code should be minimal.

The Results

No changes in reaxt-exemple

No errors in the terminal or browser console

Rename "components" folder to "src"

Obviously we have an error in the terminal

** (exit) an exception was raised:
    ** (ReaxtError) JS Handler Exception for %{...}: Error: Cannot find module './components/App'

Reaxt use the default configuration and is looking for "components" folder

Rename + Reaxt config

To add the config, we need to give Reaxt.render! the src_folder option.
Exemple :

data = %{src_folder: "src", ...}
render = Reaxt.render!(:App, data, 30_000)

From here it can works, depends on your previous JS implementation of reaxt_server_render.
If the terminal doesn't show any errors but your webpage is broken and browser console say:

Uncaught (in promise) Error: Cannot find module './components/App'

That means that in the JS part, the component given in the callback function of reaxt_server_render doesn't have any props, and the component should have at least the src_folder as prop from the first agument.
Exemple:

reaxt_server_render(params, render) {
  render(<App src_folder={params.src_folder} />)
}

After that the implementation should be complete without any errors in the temrinal or browser console.

Troubleshooting

Please refer to the Result section with the possible bugs explained

@Shakadak
Copy link
Member

Have you considered using reaxt's :global_config fields in the elixir config ?
Something of the form:

const reaxt_config = require('./config.js')
reaxt_config.src_folder

Also, I don't really understand why it is necessary to feed a prop to a component App in

reaxt_server_render(params, render) {
  render(<App src_folder={params.src_folder} />)
}

@D4r1u5K
Copy link
Author

D4r1u5K commented Sep 30, 2024

I thought about config files but i follow "Try to make the least amount of change as possible" instruction in the KBRW contributing guidelines, so as first iteration i kept it a minimal as possible. I'll dig a bit more on the config file idea

The SSR render pipeline of Reaxt is : Server -> Elixir -> Reaxt -> HTML/JS/CSS files -> Client -> JS render
The Reaxt render in server and JS render in client must have the same config to render the same result.
On the server side, the entry point of render is Reaxt.render!, so config is given here.
On client side the entry point of render is

In server side layout.html.eex :
<script><%= render.js_render %>.then(function(render) { return render("content") })</script>

In client side, HTML of a page
<script>(window.reaxt_render.apply(window,["App",null,{},null])).then(function(render) { return render("content") })</script>

To render the client HTML script, Reaxt use the props of the component given to render in reaxt_server_render, and this is the normal usage of Reaxt.

I specified my point about reaxt_server_render for 2 reasons

  • The reaxt-exemple is not setup properly for a complete usage, but for a minimal usage it's working.
  • Other usage of Reaxt usually setup it correctly but can cherry pick the props. In this case src_folder is needed in the cherry picked list.

In the case there is no cherry picking of props and the setup is just

reaxt_server_render(params, render) {
  render(<App {...pramas} />)
}

Then it should work perfectly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants