ractivejs / ractive

Next-generation DOM manipulation
http://ractive.js.org
MIT License
5.94k stars 396 forks source link

Extending component files #3332

Open p3k opened 4 years ago

p3k commented 4 years ago

Description:

I know about and (I think) I understand Ractive.extend() so far.

However, if I am using Ractive component files how would I apply the extension mechanism then? Is it possible at all?

Versions affected:

0.9.10

Platforms affected:

Ubuntu 18.04.4 LTS

evs-chris commented 4 years ago

If you're using the ractive bin to compile your components into js, then in the sub component, you import the target compiled file, which is really dependent on how you're handling your build or loading. For instance, the playground uses rollup to build a bundle to shunt into the output iframe, and you can extend a component like this (check out the files menu on the right).

If you're using a client-side loader, it's more or less the same - load the base component from the extension and extend it.

p3k commented 4 years ago

thanks for the explanation, @evs-chris. i can confirm, importing a component file works just as you say.

however, i am confused by the $TEMPLATE variable(?) – which obviously gets replaced with the actual component file’s template… just not by ractive, i assume (because i get a $TEMPLATE is not defined error); is this a feature of the playground only? done by rollup? (we are using webpack.)

in the docs, the example component file is made of require() calls and the component.exports setting instead of import and export statements – and the template is added without any further ado.

what is the difference between both approaches? are they interchangable? should everything work the same no matter which variant i use?

p3k commented 4 years ago

i tried the require() variant in the playground but it seems the loader does not like it. when i run the following files in my installation with webpack i get a Ractive no longer supports multiple inheritance. error…

app.rc.html

<script>
    const Foo = require('./foo.rc.html');
    const Bar = require('./bar.rc.html');
</script>

foo.rc.html

<h2>I am {{ name }}.</h2>

<script>
    component.exports = {
        data: { name: 'Foo' }
    };
</script>

bar.rc.html

<script>
    const Foo = require('./foo.rc.html');
    Bar.extend(Foo);
    component.exports = Bar;
</script>
stack trace
ractive.js:19031 Uncaught Error: Ractive no longer supports multiple inheritance.
    at extendOne (ractive.js:19031)
    at Array.reduce ()
    at Function.extend (ractive.js:19014)
    at Object. (bar.rc.html:11)
    at Object../apps/mobile/bar.rc.html (bar.rc.html:11)
    at __webpack_require__ (bootstrap:19)
    at Object. (app.rc.html:5)
    at Object../apps/mobile/app.rc.html (app.rc.html:145)
    at __webpack_require__ (bootstrap:19)
    at Module../apps/mobile/entry.js (entry.js:1)
evs-chris commented 4 years ago

There are two different, but very similar component types that Ractive supports. The one in the documentation is entirely runtime and requires a runtime loader like ractive-load based on rvc. The other type is entirely compile-time and requires a build step, probably using a build tool like rollup or webpack. The ractive binary, included since 0.9, I believe, will compile a ractive component and replace a handful of special placeholders like $TEMPLATE and $CSS with the parsed and processed equivalent from the component file. The playground uses the rollup bin plugin to compile single file components in the playground.

Since you're using webpack, you can author components in the same way and use the webpack bin loader and the same syntax as the playground example. If you're using .rc.html as an extension, you may need to tweak the loader config to handle those files. component.exports = { data: { name: 'Foo' } }; Try setting up webpack with the bin loader and these:

app.rc.html

<Bar />
<script>
    const Foo = require('./foo.rc.html');
    const Bar = require('./bar.rc.html');

        const App = Ractive.extend({ template: $TEMPLATE, components: { Bar } });
</script>

foo.rc.html

<h2>I am {{ name }}.</h2>

<script>
    module.exports = Ractive.extend({ template: $TEMPLATE, data() { return { name: 'Foo' }; } });
</script>

bar.rc.html

<script>
    const Foo = require('./foo.rc.html');
    module.exports = Foo.extend();
</script>

You can also use ES6 module syntax with webpack to be slightly more cross-tool compatible. The only thing that changes there is the require and module.exports usage. The ractive bin uses placeholders because it lets you put anything you want in your component files, including multiple component definitions per file. Also, the example bar.rc.html could just as easily be a .js file, as it doesn't have any template or css involved. Since the ractive bin doesn't care about anything in your component other than the template and css, you can also use typescript or other compile-to-js languages as your script. The bin even has a mode that just exports { template, css } for semi-typesafe component building with typescript.

p3k commented 4 years ago

darn, although i even starred ractive-bin-loader i totally forgot about it… it works! and so much better than the ractive-component loader. thanks, @evs-chris.

that’s great news on the one hand, on the other it’s a little bit sad to find it out the hard way – at least i did not remember to read about this alternative approach in the docs. (just took another coarse look with the same result.)

and last but not least, while component files are mentioned and described in the documentation, they obvisouly only work with the ractive-component-loader – which just from its name of course seems like the first choice to go (and potentially become stuck) with.

maybe the docs could need some update in this regard? the component files page itself even links to a non-existing loaders page (right at the bottom)…

either component files as described on that very page are not hip anymore – then maybe communicate they are not recommended or even deprecated. otherwise it would be nice to get the full picture of how component files can be written, which loader they need, and what obstacles there might be using them. (your reply above would be a great start!)

i would even assign this task to myself – but unfortunately, the company i am working for is reconsidering right now whether to replace ractive with a different framework. and documentation issues like these are one reason, to be honest…

evs-chris commented 4 years ago

Yeah, the docs are not in the greatest shape, as that's something I'm particularly bad at. I'm currently the only active maintainer, but for the most part ractive is pretty stable. I have plans to rewrite the docs in a more concise api-based style and clean out the some of the years of aggregate cruft. I also have plans to try to rewrite a few parts of ractive to lose some of 60% overweight it's gotten. Unfortunately, I don't have much free time right now, so as long as there are no immediate bugs, I'm not really getting any work done on any of that.

Open source front-end libraries are a bit of a dangerous gamble. Svelte is my favorite of the current generation by far, but I'm not positive that it has enough of a core dev team for me to be comfortable choosing it without also being able to do maintenance myself (which I am, but there are a few things keeping me from being able to use it as a first choice for most of what I do - big heavy back-office apps that seem to stick around for ages with no budget to significantly improve). You're also subject to never ending best practice changes. I don't really have a particular point, I just wanted to say that the front-end landscape and pacing stress me out. That's why I picked ractive ages ago and have stuck with it for this long - despite its handful of warts (docs and weight being the largest), it's fairly unique and very effective for what I need. It even has a reasonable typescript path aside from whatever happens in the template - and that seems to be an issue for all of the template-based frameworks.

giovannipiller commented 4 years ago

Open source front-end libraries are a bit of a dangerous gamble

100% agree.

I don't really have a particular point, I just wanted to say that the front-end landscape and pacing stress me out. That's why I picked ractive ages ago and have stuck with it for this long - despite its handful of warts (docs and weight being the largest), it's fairly unique and very effective for what I need.

One of the reasons I love Ractive is that its core concepts are simple, yet it's powerful enough to build complex stuff. It's been also quite easy to introduce new team members to it.

Yeah, the docs are not in the greatest shape, as that's something I'm particularly bad at. I'm currently the only active maintainer, but for the most part ractive is pretty stable.

I've been using Ractive since 0.7.x, and especially since 0.9.x, Ractive has been a pretty reliable tool. I haven't said this enough times: thank you Chris.

p3k commented 4 years ago

Yeah, the docs are not in the greatest shape, as that's something I'm particularly bad at.

did not want to point any fingers because i know how hard documenting is, generally – and for a changing and growing codebase, especially.

I'm currently the only active maintainer

i admit that’s worse than i suspected; i assumed it might be at least a fistful of people… for that you are doing an amazing job @evs-chris and i also would like to emphasize how precious your and the community’s support and assistance always was. thanks a lot.

nevertheless, one human being solely responsible for maintaining a whole front-end framework raises indeed a red flag for me nowadays. (so much for the dangerous front-end library gamble.)

but for the most part ractive is pretty stable.

on the one hand it in fact feels like it is. but then again if one – like me – does not know the inner workings too well, and the documentation does not tell you either, the feeling begins to wear off.

I have plans to rewrite the docs in a more concise api-based style and clean out the some of the years of aggregate cruft. I also have plans to try to rewrite a few parts of ractive to lose some of 60% overweight it's gotten. Unfortunately, I don't have much free time right now, so as long as there are no immediate bugs, I'm not really getting any work done on any of that.

that sounds ambitious and defensive at the same time :wink: i guess the 90% of open source projects out there are run like this. and righteously so because we need them, they bring the necessary diversity.

Svelte is my favorite of the current generation by far, but I'm not positive that it has enough of a core dev team

in our decision-making process svelte got a huge bonus because of its conceptual freshness – but placing our bets on another “rich harris framework” just did not feel that attractive, anymore.

I don't really have a particular point, I just wanted to say that the front-end landscape and pacing stress me out.

for sure trying to catch up with these developments is stressful. but so can be sticking with your long-time framework and coping with a lack of developer tools and third-party integrations, too… your mileage may vary.

to conclude this post, i let you know we picked vue as our framework of choice. it’s community-based (and thrivingly so), very well documented, and looked the easiest to migrate from ractive to. and yes, its popularity was another reason, it might have some impact on recruiting.