enonic / starter-react4xp

React4xp starter with examples, for Enonic XP7
Other
4 stars 1 forks source link

Dealing with relative paths #7

Closed sigdestad closed 4 years ago

sigdestad commented 5 years ago

In the hydrated example i find the following:

return React4xp.render( request, { component, props: { greetee: component.config.greetee }, jsxPath: 'site/parts/example/example', }); };

How does jsxPath work? Currently, this behaviour is strange, why not use ../example/example instead? I would like (to the extent possible) that path referencing was as natural as possible. In this case we simply start with 'site/' - how does this compare to how we use the "resolve()" function elsewhere?

espen42 commented 5 years ago

Agreed, this doesn't follow that part of the conventional XP way.

First off, jsxPaths aren't actually paths, but names referring to post-transpilation JS entries (so 'jsxPath' may be a bit of a misnomer I guess):

https://github.com/enonic/lib-react4xp-runtime#jsxpath-how-to-refer-to-a-react4xp-component

So, this adds one concept to learn. But there are a couple of reasons for doing it like this:

1, it has to be a post-transpilation reference (OR a prediction to it from a pre-transpilation path, but that makes it harder to handle a non-rigid project structure - which is the aim of react4xp-buildconstants: customizability), and since compiled XP and React components both transpile to JS files, the post-transpilation react components can't be in the same folder as the XP ones (or at least, can't have the same name, but that would break a different part of the XP naming convention). Currently, the react components are transpiled into a different root folder than the XP components - namely resources/react4xp. That makes a direct post-transpilation reference more cumbersome.

2, It's a completely consistent pattern across all the places it's used. Once you know a jsxPath, you can refer to it from an XP component, from the client for rendering, or from the client or a controller to get its dependency chunks. This also ensures that JSX components are handled in one single way, whether they are "XP-component bound" under site/ or they are "independent". Consistency makes stuff predictable for the developer, and non-rigid for use cases where a custom structure/approach is needed.

3, It's predictable from the file structure, AND you can look all the jsxPaths up after building, in resources/react4xp/entries.json.

Suggestion for a workaround that keeps these advantages and gives a closer-to-XP-approach: Since the source .JSX files are copied to the site/... folder and exist after build, we could add a resolvedJSX parameter to React4xp.render(Safe), which takes the output of resolve('./relative/path/from/controller/to/component.jsx'), and under the hood transforms it into the needed jsxPath. It's probably a good idea to rename the jsxPath concept then, to not confuse the two, for example to entryName.

espen42 commented 4 years ago

Collecting general-architecture issues in one common repo: lib-react4xp. This one is moved to https://github.com/enonic/lib-react4xp/issues/23