-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Add support for mixins #1041
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
Comments
+1 for declarative way to set up observers maybe same for event listeners |
I've recently been working on a project that's MVC styled using Svelte's Store. Separating everything correctly hasn't left any space for needing mixins and so I'm very interested in the situations that you foresee mixins being used for. |
Unfortunately, the proposal outlined above isn't possible without majorly rethinking how Svelte is architected — I'm going to focus on When Svelte compiles a component, it checks to see if there is a For example, this... <script>
export default {
computed: {
c: b => b * 2,
b: a => a * 2
}
};
</script> ...results in this: App.prototype._recompute = function _recompute(changed, state) {
if (changed.a) {
if (differs(state.b, (state.b = b(state.a)))) changed.b = true;
}
if (changed.b) {
if (differs(state.c, (state.c = c(state.b)))) changed.c = true;
}
} If we had a computed property in a mixin, Svelte wouldn't know about it — it wouldn't be able to generate that code. Now, we could fix that, if we were highly motivated: the compiler could look at the At that point, it would have the extra knowledge it needed to generate the function correctly. But it could break in a dizzying number of ways. What if the mixin was written in TypeScript, or needed to be transformed by Babel? Does Svelte now need to know about those? What if it's imported from npm — does Svelte need to know how to resolve files in The file itself would have to be written with some fairly tight constraints. What if a new developer on the team thought 'you know, this would be easier to read if we did it this way instead': import fullName from './computed/fullName.js';
const mixin = {};
mixin.computed = {
fullName
}; Oops, you just broke everything, and now you have to explain to your team member why this particular JavaScript module, unlike all the others, has to be written in a very particular way and can't rely on the Babel transforms or injected variables the rest of your app is using. As you can see, the complexity soon becomes completely overwhelming. No new features get added to Svelte, because we have to spend all our time dealing with the edge cases that fall out of these new requirements. Now on top of that, it's far from clear that mixins are actually the right way to solve the problem at hand. As I've expressed elsewhere, it makes it much harder to understand what a component's capabilities are. And there are some real issues that arise when you have multiple mixins in a component, as the React community found. You can share code between components — I often have a central import { formatDate, addCommas } from '../helpers.js';
export default {
helpers: { formatDate, addCommas }
}; ...and it's much easier to see when you actually no longer need, say, I'm not unsympathetic to the idea that certain forms of code reuse could be made easier, but hopefully this spells out why I think there's a high barrier. |
I don't use MVC architecture because it's too bulky. Just look what MVC is really mean - http://vuemc.io/. I don't think you could do the same with Svelte. I wonder, how you suppose to resolve the case which I describe above - then we need to have a complex User-model in multiple components. As you can see, there are many things depending on each other (for example, fullName depends on firstName and lastName). So we can't declare all these things separately because it can cause discrepancies and hard to control.
Perhaps, it should be at the time current architecture doesn't allow to implement new features?
If you say that Svelte compiler nothing know about filesystem and actually don't import dependencies, so how it works with these things and what differences:
So, is it mean that now we are limited to use the module from node_modules and even from our own project folders, right? It turns out that I can't do these things:
How does it suppose to be? How can I write the serious application without 3rd party modules? It's a nonsense!
It's not a problem because we already have many constraints when writing Svelte-components. We can suffer it, using svelte-mixins too because it's not the "some module" but a special type of the module.
I used mixins with Ractive many years and my experience gives me a good results. Concerning React-guys, I think that it the only opinion of Dan Abramov. Just check the comments below that article. How can we trust the guy who has created so silly thing as Redux?
Oh, so how you import that files if Svelte compiler nothing know about file-system? And why we can't import an object from the same place? Or maybe you have an idea how to solve the task I described above in this way? You don't want to tell what I should do so:
It's weird and can bring us to inconsistent cases. |
It allows us to implement lots of new features, and our roadmap is very full! Just not this new feature.
Of course you can import stuff — Svelte just doesn't know (or care) about what's inside the files you're importing. It leaves the
Yes, you can. Of course you can! That would be insane if you couldn't.
There's a huge difference between those constraints existing in an |
Ok, can we at least implement component.use() feature? And also declarative observe and on ? Perhaps it will reduce the pain...
So, why I can't import a simple object? Do you analyze Svelte components on the fly? I thought that you use something like posthtml-parser to parse the file to separated parts eg "style", "script", "template" and after execute js to get exported object or something like that. And only after that analyze the code.
Ok, it could be .mixin extension. It doesn't matter. |
I actually have been doing the same thing with Svelte! https://twitter.com/PaulBGD/status/944058331290898432
You can put firstName and lastName in a Store (or the highest svelte component, but I try to avoid that with MVC), then compute the fullName. Features like mixins seem really handy initially, but it creates bad patterns and causes a lot of code change just to add simple features. |
Hm, controller, models, all is svelte-components? What markup you provide in these things? Actually, I don't udnerstand. Could you please provide some examples of controller and model?
I don't get it. Store is OK, because it propagated to all components tree, but how adding this things to top component will helps me to get these props in child components? All components are isolated. Could you please provide some example too?
As I already said, I'm using mixins with Ractive many years and my experience gives me a good results. |
Here's an example: https://svelte.technology/repl?version=1.49.1&gist=47dfce0e82992650aad8233cf5d12ac7 A similar pattern when you use fullName a lot with different variables would be to create a helper for it like Rich suggested and that'd look like this: https://svelte.technology/repl?version=1.49.1&gist=71e731d94534749ee5addfdbad326021 I'm not going to suggest that MVC is the official, only pattern of using Svelte, however I personally think it leads to better code quality than mixins. |
Wiki:
I don't see any parts of this pattern in your code. Only titles. If this code is good for Svelte, so..it's regrettable. So, if you need have a props firstName and lastName and computed prop fullName, and also additional method login() in multiple components, you would define it in each? How many time you could do that before you will be tired? |
@Rich-Harris It's a pity, but I think we can skip the questions about mixins and plugins. I checked the source code a little bit, seems you're right. How about observe and on ? UPDATE: I'll raise a new issue for this part. |
sync svelte docs Co-authored-by: Rich-Harris <[email protected]>
Hi everyone!
To continue the conversation begun in a chat, I want to suppose my vision of Mixin implementation to Svelte.
Theory about mixins
Wikipedia
Medium article
Vue mixins
First of all, I don't want to violate Svelte's simplicity. That's why I'll try to design my proposal so simple as I can.
So in my opinion, Svelte's mixin need to be just a POJO-object that just reflects already used "options" object. If we accept it everything else becomes so simple. For example, User.js mixin could look like this:
And used like this:
So, just like Vue does. Under the hood, Svelte just need to merge all these props together, for example like this:
And we just need to apply this function to all mixins sequentially:
I think it's not so hard to implement but gives us many advantages.
Also, I think we really need to have a declarative way to set up observers and event listeners. It could be implemented just like Ractive does:
Also, we could provide something like Vue's plugins which is just a function invoked in Component's instance context. Basic implementation looks like this:
In difference from Vue, in my vision, plugin works with the concrete instance, not with global things.
Mixins and plugins both need to good separation of the code to modules. Mixin more declarative thing, it needs to construct an object. Plugin for imperative usage, to add some stuff to the instance.
@Rich-Harris if you too busy, I can create a PR for these features if you'll show me the right way to do these things.
@ALL, if you, guys, have your own proposals feel free to join the tread!
The text was updated successfully, but these errors were encountered: