riot / ssr

Riot.js node Server Side Rendering
MIT License
32 stars 8 forks source link

Cannot render child components pt 2 #18

Closed damusix closed 4 years ago

damusix commented 4 years ago

Continuing https://github.com/riot/ssr/issues/17

Hey man, it'd be nice if we could have a discussion instead of just abruptly closing the issue. I've read the riot documentation and I am genuinely confused. Maybe you can help me think this through? I see that here: https://github.com/riot/ssr/blob/master/test/core.spec.js#L39 you are including the child component within the parent component. I am trying to use Riot as a template engine for @hapi/vision. Having to manually import every single component you want to use in a template doesn't seem scalable if you have some heavier templates with many components. Is there a way to register all components into memory so that you don't have to think about having to import other components server side? Or am I thinking about it the wrong way?

damusix commented 4 years ago

Not sure if maybe this is a better discussion for discourse, but docs aren't clear about global registration. The readme only highlights the various things that you can render, and not whether it can be approached identically to how you would in a frontend app.

GianlucaGuarini commented 4 years ago

Having to manually import every single component you want to use in a template doesn't seem scalable if you have some heavier templates with many components.

That's how SSR works, it's not Riot.js specific. In Django CMS you use the {% load %} syntax in React.js you import your subcomponents in Vue.js you import components the same as you do for React.js and Riot.js

Having to manually import every single component you want to use in a template doesn't seem scalable if you have some heavier templates with many components. Is there a way to register all components into memory so that you don't have to think about having to import other components server side? Or am I thinking about it the wrong way?

Riot.js can mount child components if they are imported locally in your parent components for example:

<my-parent>
  <my-child/>

  <script>
    import MyChild from './my-child.riot'

    export default {
      components: {
        MyChild
      }
    }
  </script>
</my-parent>

Or if they are registered globally with riot.register for example

import MyChild from './my-child.riot'
import { register } from 'riot'

register('my-child', MyChild)

All these informations are written in the documentation linked in the issue you have already created and that I have closed

Nested tags should be registered via riot.register call or they can be directly imported into the parent component.

So far nobody until now had problems understanding this part of the Riot.js documentation, have you any suggestion to improve it?

damusix commented 4 years ago

That's how SSR works, it's not Riot.js specific. In Django CMS you use the {% load %} syntax in React.js you import your subcomponents in Vue.js you import components the same as you do for React.js and Riot.js

Yes, except in React, you don't have to register components. Compilation is abstracted away via webpack, you just use them as pseudo-HTML. In almost all side rendered templating languages (ejs, erb, eex, handlebars, etc), you don't worry about registering within the template itself, it is all resolved for you. This similar behavior is what I am trying to accomplish.

My goal is this:

<message>
     <p>{ props.text }</p>
     <by-line author={ props.user }></by-line>
</message>

and not so much this:

<message>
     <p>{ props.text }</p>
     <by-line author={ props.user }></by-line>
     <script>
         import ByLine from './by-line.riot'

         export default {
             components: {
                 ByLine
             }
         }
     </script>
</message>

So far nobody until now had problems understanding this part of the Riot.js documentation, have you any suggestion to improve it?

It's not about misunderstand Riot docs; they are very clear. It's the SSR readme that is unclear. This in particular https://github.com/riot/ssr#register---to-load-riot-components-in-node.

The word register correlates with the action of registering a component to Riot like it states in the docs https://riot.js.org/api/#riotregister even though the functionality is to load, process, or transpile a Riot tag. I would suggest either adding explicit commentary stating that @riot/srr/register !== riot.register, or changing the name of that function to something else that is more semantic and less confusing. That completely threw me off.

It would also help to explicitly state that SSR can be treated exactly like CSR, if that is the case, in that you can register a component globally without needing to include in other components. To me, the SSR readme tells me "This is specifically how you SSR", and not "Riot in Node is very similar to Riot in Browser, and this is how you SSR".

Maybe some more in-depth examples would help too. In either case, I'm going to be trying to use this exactly like I do on web and can provide some samples and improvement to the docs. I'll close this if all is good and make some PRs against the docs if it's OK with you.

GianlucaGuarini commented 4 years ago

Yes, except in React, you don't have to register components. Compilation is abstracted away via webpack, you just use them as pseudo-HTML. In almost all side rendered templating languages (ejs, erb, eex, handlebars, etc), you don't worry about registering within the template itself, it is all resolved for you. This similar behavior is what I am trying to accomplish.

That's not true check for example:

However I don't want to debate about this topic and let's focus on Riot.js.

The word register correlates with the action of registering a component to Riot like it states in the docs https://riot.js.org/api/#riotregister even though the functionality is to load, process, or transpile a Riot tag. I would suggest either adding explicit commentary stating that @riot/srr/register !== riot.register, or changing the name of that function to something else that is more semantic and less confusing. That completely threw me off.

@riot/ssr/register is a common pattern used already by many other javascript libraries allowing the compilation of (custom) files loaded via require calls for example:

However if this topic is not clear from the documentation PRs are welcome.

Regarding the registration of global components you can simply use a similar strategy on the client and using glob on the server.

damusix commented 4 years ago

@GianlucaGuarini You are correct. I mispoke when I said you don't register, what I meant was, the instantiation of these components is simpler with a 1 line <%= include 'mytemplate' %>, which is the equivalent of <mytemplate></mytemplate> .. I just wanted to eliminate that awkward import within the template. I have resolved my issue.

I will help with a PR to docs. Thank you for you work and attention.