-
-
Notifications
You must be signed in to change notification settings - Fork 407
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
Splitting Ember into packages #284
Conversation
Beautiful! |
It's unclear to me from the RFC, but will Semantic Versioning be respected in Given the given example from the RFC, let's assume Ember 3.2.0 is released and it splits out What are the trade-offs between those, and which is the current plan? |
I find some are unclear for addon authors. This RFC is pretty dense, so I might just as well be misunderstanding something. |
Am I in the minority of wanting one "monolithic" ember package? I'd rather have everything "ember" at my disposal, then have tree-shaking remove the un-needed stuff on build (shake not only my app code, but what pieces of ember are not being used by the app and addons, etc.) Just seems like this would add so much more complexity when tree-shaking could take care of the job. Or am I missing something? |
@Panman8201 that is achieved here. If you want "everything ember" you'll continue to use |
@Panman8201 I think you are definitely in the majority. I think most users wouldn't have to worry about this at all, and as long as they continue to use You only need to do this if you are very filesize-conscious (I personally think most apps – at least most "productivity" kind of desktop apps aren't in that category). But it's nice that people in that category can do it if they want to. |
Also, I don't think tree shaking can be very effective at removing the kind of features we are talking about here. For example, Mixins, computed properties and observers are all features that are deeply weaved into different parts of the framework. Even if you are not importing the macros in your app the Not that it's impossible, but the bundler would have to get really smart and have a lot of knowledge about Ember's internals to do it correctly. |
When you run the upgrade command, it will edit your |
@chancancode I understand that the proposal includes an upgrade command to help manage breaking changes in A potential problem with this being a minor version bump to |
@cibernox that is the point of the "required-core-features" system. It is basically saying "this addon was last audited as of version 3.10" – so if version 3.11 splits out two additional packages (say So everything will still work, but your build might not be as lean as your hoped (it will be no worse than before the upgrade, though). You can use the override feature to test if anything breaks if you insist to remove those features and send a PR to the addon to "re-certify" it against 3.11. |
@Kerrick at the moment |
@Kerrick I don't think that is true. The only relevant concept in Semver is "public API", which is intentionally very loosely defined:
As part of the documentation, this piece of software communicates to the users that "the only supported way to upgrade is to use the upgrade command", which does whatever it needs to do to maintain the API compatibility for you. It is also absolutely not true that you don't have to use "external tools" to maintain compatibility. In practice all node packages have the implicit requirement of "the only supported way to upgrade is to use an NPM-compatible package manager" (where "NPM-compatible package manger" is not even that well defined). If you try to upgrade a package simply by downloading the tarball of a newer minor version and extract that into the appropriate location in your It is just a matter of clearly defining what you consider the "public API" and communicating that clearly with your users, which is why even things like legal documents could be considered "semver-compatible". |
text/0000-explode.md
Outdated
|
||
We propose adding an *additional* supported way to depend on Ember. You can choose to run `ember explode`, and we will remove `ember-source` from your dependencies and replace it with `@ember/core` *plus the current complete set of already-extracted Ember packages*. `ember explode` is intended to not change the set of Ember features in your app. It just splats them out into a form that comes from separate packages. | ||
|
||
Critically, `@ember/core` includes an extra rule in its semver policy: the only supported way to upgrade to a newer `@ember/core` is to run the `ember-cli-update` command. The update command will be aware of any additional packages have been split off from `@ember/core` since your last version, and it will add them automatically to your app. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
until now ember-cli-update
is responsible for updating ember-cli
, I fear that this change force ember-cli
even more into lockstep with ember-source
🤔
text/0000-explode.md
Outdated
|
||
If one of the newly-split-off Ember packages depends on another, it will say so in its NPM peerDependencies. We will use exact-version constraints, which is effectively how things already work today. | ||
|
||
NPM has historically been loose about peerDependencies, so they are often ignored by developers. We propose that ember-cli should hard error for missing peerDependencies to avoid this problem (most people who think they don't really need to clean up peerDependency warnings are simply mistaken, and have latent bugs). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have discussed this in the CLI calls and I am very much against a hard error without any escape valves
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the only part that jumped out at me too. Hard errors might cause more pain than what it would be trying to solve. At least once I got peer deps unsatisfied warnings from NPM, where I knew my setup was more correct than NPM's algorithm. I think we should roll this out without hard errors, then bring that discussion up when it becomes a problem.
"@ember/component" | ||
] | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does this format address overriding incompatible peer deps?
|
||
In the case of code we want to remove, splitting it into separate packages doesn't eliminate our need to support it (at least until the next major release lets it be truly removed). So while this proposal lets us "go faster" in some senses, it doesn't let us reduce support any faster. | ||
|
||
# Alternatives |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if static (import) analysis to figure out what Ember features are needed would also be a valid option instead of declaring the features explicitly 🤔
and FWIW I tend to agree with @Kerrick that |
What @chancancode said in #284 (comment) was quite helpful to me to clarify the difference to only relying on tree-shaking. Maybe something like this could be added as another "How this relates to" section? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I am lukewarm to having all this new configuration. I would strongly prefer to look for ways not to import all of Ember automatically, like tree shaking, static import analysis, etc.
text/0000-explode.md
Outdated
|
||
# How We Teach This | ||
|
||
The most important message we need to teach app developers is: use `ember-cli-update` whenever you're changing your Ember version. As long as we can spread that message, we can provide direct guidance the rest of the way. For example, when we reach a sufficient level of confidence in the `@ember/core` packaging, we can begin making `ember-cli-update` offer to automatically explode `ember-source` into `@ember/core` *et al*. This would be a simple code mod that should not alter any app semantics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should ember-cli-update
be added to the default blueprint? I think it would make it easier to set up and teach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, whatever upgrade command we use should be in the default blueprint. It doesn't necessarily even need to be ember-cli-update, it could be something new. I just picked that one because it's the best one that already exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping "npm-SemVer" would lessen the strain here. You would still have to teach people to cope with frequent major versions by using the provided magic. But you wouldn't lose people along the way that you haven't reached yet.
"required-core-features": "3.1.0", | ||
"required-additional-features": ["@ember/routing", "@ember/prototype-etxensions", "@ember/string"] | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm really concerned this puts additional burdens on addon developers, who already have to do a lot. Will this be expected of most/all ember addons? If a single addon doesn't do this, it will be assumed that all of ember is required? Will addons be continually pressured to update "required-core-features" with every release of Ember?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an area of legitimate concern, and one I thought about a lot when writing this RFC. Here is my reasoning.
My goal here is to enable people who choose to spend effort on getting code out of their apps to be unblocked from doing so, and that people who don't choose to spend effort on the whole thing should not be impacted. For app authors, I think the proposal clearly achieves that goal.
For addon authors, there is this one-line change in package.json that I am indeed requiring, if they want to make it easy for some of their advanced users to start dropping Ember packages. To make that one-line change as easy as possible, I have introduced a mechanism (dependency-overrides.js) that allows the people who are motivated to do the work (the app authors who are trying to remove packages) to do all the testing for you.
The blueprint for addons already puts them into the strictest possible conditions (like disabling prototype extensions) for testing against the widest possible set of Ember apps. What I'm proposing is not different than that. When it's time to add a new ember-try scenario for the first release that offers @ember/core
, best practice will be to just test against @ember/core
instead of ember-source
so that you would see right away if you're still compatibility, making the decision to update required-core-features
as easy as possible.
I hear what you are saying about completely automatic code removal being better, but it is fundamentally not possible for an awful lot of the code, short of changing Ember's programming model to be much more verbose to make every kind of dependency static and explicit.
|
||
We have already proposed making missing dependencies a hard build error. This is important so that weird and frustrating bugs don't crop up unexpectedly. But it needs to be possible to get oneself unstuck without being blocked by third-party code. | ||
|
||
Therefore, we propose a `config/dependency-overrides.js` file that allows you to make declarations on behalf of any addon: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ember should be striving for zero configuration. This adds lots more configuration that will need to be regularly updated if a user wants to use a recent version of Ember. Right now, on Ember Observer, I did a quick search and found just 17 addons whose package.json
is up to date with the most recent version of Ember.
I strongly encourage you to rethink this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of this configuration is required in any app. This is purely about making it not impossible to spend more effort if you want to make your app smaller.
Apps are free to ignore 100% of this RFC and will always be free to do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question for me is to what extent this RFC will impact addon developers, not app developers.
This seems cool and I could see how it could make the life easier for the maintainers of Ember. That said, it seems like it would be a lot of effort and I'm struggling to see the real value it offers to Ember's end users. |
This is a misunderstanding of semver. "Public API" it not limited to things like which functions are available. It can include whatever other conditions you want to impose. What is important is that you state clearly what is the supported way to use the software, and anyone who follows those instructions is safe. So no, we would not bump major versions of |
The important thing here is that in none of those situations is anybody worse off than they are right now. Even if you're using The only time you need to do extra work is if you get motivated to try to remove some of those newly split-out packages from your app. |
If it's a misunderstanding of semver, it is likely a common one. Everything from third-party tools like David DM and GreenKeeper to the
*If you use the built-in tool and don't use any third-party tooling that has been built around the common community understanding of semver. I'm all in for splitting into multiple packages, but I think that serious thought needs to be given to allowing the major version numbers of Google does a similar thing with |
I agree with @chancancode that many of the apps that are using Ember today shouldn't care about this at all. You're not wrong when you question the value to current Ember users. But the goal here is to enable a whole new class of apps to become Ember users. Apps that today would not have chosen Ember because it's "too big" or "too much to learn". We can create a more comfortable adoption path for all those apps. |
If the hope is that these sub-packages can become an adoption path for new users to the Ember ecosystem, it’s even more important that they follow the common version of semver on their own, without breaking changes inside a single major release. Let’s say a creator of that whole new class of apps decides to use Now let’s say that In an alternate world, |
@Kerrick ah, you are hitting on some important points I did not consider. I should probably say explicitly that the upgrade rule applies to Your point still stands that We are also working within the limitations of NPM, which makes meta-packages not really work well. It would be ideal to just have an If somebody wants to figure out how to make a meta package work well, I would be happy with that alternative. I have gone pretty far down the path of trying to design that, and each time discovered I would need to do "weird" things that NPM doesn't normally do to make it work. |
What's the minimum package set that makes Ember, "ember"? I had thought until now that |
That is the question, isn't it ;) How I view this initiative is that we want to allow users to opt into a smaller subset of Ember than
I am not sure I fully understand this point, as we have already broken Ember into separate packages.
Hhhmm… ;) |
If you can folks make it possible to extract ember-data outside ember to use it as a standalone API wrapper, I think it will be huge win. Apart from that, splitting ember into packages seems quite reasonable and the way to go. |
I do understand and agree that this RFC is in line with "vanilla" SemVer, but as @chancancode wrote:
So, in essence, this proposal would introduce a way to use Ember, that is in fact outside the "NPM-compatible package manger"-ecosystem, but looks weirdly like it was part of it. @Kerrick has given a perfect example (Strings etc) how that would hurt. One way to deal with this would be to have |
Honestly this feels like a facade. I can't imagine someone deciding, "I'm just going to pick up the Ember core and the router, but not use services or components". Because even if these things are decoupled at the package level, they're still part of the same ecosystem. Guides, Docs, Tutorials, Addons, etc would all have to take extreme care to explain and enforce this.
It's also about the time and resources that go into this project that could be spent elsewhere. Not just the author's time, but those who review code changes, testing, documenting, reporting bugs that arise, etc. |
The likely scenario is to start with just components. I absolutely agree with the premise that most real apps will eventually need most of what's in Ember. But the problem is lots of people don't understand that when they're getting started, so they pick a component-only library over Ember, and then end up reinventing all the other stuff as they go, much to their lost productivity and stability, and to our loss as a smaller community.
This proposal is deliberately intended as infrastructure that should make everything else go faster, not slower. That is why I wrote this RFC in the first place. I don't happen to be a user that is obsessed with byte size. I'm motivated by strategic efforts to help the whole community ship faster. There is still plenty of old and broken stuff floating around in Ember that nobody has stepped up to fix because there's no near-term payoff, since even deprecated stuff needs to stay around for quite a long time. This proposal creates a near-term payoff to fixing. It also gives us general-purpose tools for backward compatibility, such that all future changes get easier to make, because "how to swap out the old code without breaking apps" becomes a problem with a standard solution. This lowers the amount of effort required for lots of features that people want. It also creates a clear path for advanced users to experiment with next-generation replacements for things like the router. The more experimentation we unlock, the faster we can stabilize new features and bless them as the official release. Your questions are good ones and they are forcing me to be more clear than I was in the original doc. The highest-level goal of this proposal is to make it easier to ship improvements in Ember, so that more people can overcome the intimidation and effort barriers required to help. |
I believe there were some good points brought up by @Turbo87 above that haven't been addressed regarding peer deps. |
So here's the thing: virtually nobody can reasonably make this part of their normal workflow. Trying to manually resolve graphs of dependencies, while allowing duplicates "when appropriate", and resolving peer dependencies manually at the top level is just a nonsense requirement that nobody can do. The original version of this proposal tried to avoid that problem by moving the resolution for this particular problem into side-configuration, so that Ember could handle the resolution for you and avoid the brokenness of npm's peer dep warnings. However, there was strong pushback that we should just "go with npm" and not "reinvent the wheel". I'll accept either of the two, but if we're gonna go with peer dependencies, we need to be able to assume they work. If we think people will need to manually do work to get around brokenness, we really need to use the side-config approach. So which is it? |
If npm really is that broken it has to be fixed. If that isn't possible, by all means, run your own but don't do it inside the existing npm ecosystem disguised as part of it when it isn't. Maybe the peerDependencies approach with an "I know what I'm doing and don't want hard errors" config option might be a solution? |
That's essentially what I meant with "escape valve" in #284 (comment) One example where the npm peer deps warning was entirely wrong for me:
The nested These things seem to happen quite often to me and I'm worried that enforcing peer deps in the same way will create much more pain than it solves. I'm absolutely okay with displaying warnings for them, but I'm opposed to hard errors if there is no way to turn them off. Sidenote: we should consider how to implement this in Ember CLI without losing startup performance |
@Turbo87 In your eslint example, isn't the issue resolved by including In other words, it seems okay to me to say that transitive dependencies are not allowed to fulfill peer dependency requirements. The worst case scenario is you can just adopt the dependency with the same version range as the other dependency bringing it in transitively. In your example, you could add Is there a downside to this that I'm missing? |
then something like
I think the expectation is that if
Until someone updates |
Removing Final Comment Period so that we can address recent feedback... |
Has the feedback been addressed? |
Update: this RFC has been on the back burner for a while but it is still quite relevant and the text holds up well. I still think it's a good idea, I just haven't been actively championing it as working on embroider comes higher in my priorities list. The only major remaining objection was concern about making invalid peerDependencies into errors. I accept that the NPM ecosystem is riddled with problems that make keeping peerDeps valid difficult in general. My suggestion is:
If anybody has some time to take over and incorporate that into the text, I think this RFC is still right near the home stretch. |
Apply suggestions of #284 (comment)
Update RFC section on inter-package dependencies
If the latest feedback has been addressed by #646, it is OK to move this RFC along its path to be merged? |
"ember-addon": { | ||
"required-core-features": "0.4.0", | ||
"required-additional-features": ["@ember/routing", "@ember/prototype-etxensions", "@ember/string"] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just flagging that there's going to be some amount of overlap with deprecation staging config here #649. We discussed making it possible to identify "parts of ember they do not use", but decided against it. Nothing really to do at the moment, since it's not really feasible to try to expand the scope of both RFCs and there isn't anything inherently conflicting yet. Just wanted to let you know. cc @pzuraq @rwjblue.
|
||
We have already proposed making missing dependencies a hard build error. This is important so that weird and frustrating bugs don't crop up unexpectedly. But it needs to be possible to get oneself unstuck without being blocked by third-party code. | ||
|
||
Therefore, we propose a `config/dependency-overrides.js` file that allows you to make declarations on behalf of any addon: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
# How We Teach This | ||
|
||
The most important message we need to teach app developers is: if you want to use `@ember/core` during the initial phase, you should use `ember-cli-update` whenever you're changing your Ember version. As long as apps follow that advice, they should experience the same level of stability they would get from `ember-source`. As people begin to experiment with removing Ember packages, our best teaching opportunities are very clear and helpful feedback from `ember-cli` whenever they have a dependency issue, as illustrated in some of the example messages in this document. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ember-cli-update
should maybe become ember update
. Opened #653.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
What's left on this? 🤔 |
Has implementation even started? As far as I know Some preparation work has been started for sure. Some features earlier included in But a common Ember all still relies heavily on fake packages like It even gets worse if also pulling all the fake packages into account, which are less commonly used by an application itself. By far the most packages listed in Ember API docs are fake packages provided by But to be honest I'm not sure if that's still the right target. Maybe instead of splitting up existing Ember we could continue to implement new replacement as standalone packages. It's a slow transition path. But I'm also not sure if there are that many use cases which require a developer to start with I don't have much insights in core development. But it seemed as if doing so worked out quite well in the last two years. |
I still think the high-level goals of the RFC are good. I think we would want to do an updated iteration that takes advantage of all the progress we've already made recently across the ecosystem. For example, we're starting to see addons shipping in v2 format now. Since V2 addons have to ship their code in a form that's statically analyzable, we can reliably tell which Ember packages they really use. So they wouldn't need the As of now, that would cover addon usage of Ember modules via JS imports, but when you combine it with https://github.com/emberjs/rfcs/blob/master/text/0496-handlebars-strict-mode.md via something like #779, we would have full visibility into what parts of Ember are used by any addon. That solves the hard migration problem that this RFC deals with. Also, as of Ember 4.0 we made sure that apps are required to have support for v2 addon format via ember-auto-import >=2. That means we're free to ship ember-source itself as a v2 addon, which makes all usage of ember modules pay-as-you-go. So I think we're actually making huge progress in moving the ecosystem toward making it possible to ship ember as "real" packages without disruption. The next ecosystem-wide thing I'd like to do that would protect users from breakage as you move toward ember being "real packages" made out of "real modules" is deprecating all usage of |
If we are considering a revised RFC around this concept, would we ever consider allowing for the new "isolated" modules to not require glimmer as it's rendering engine? Or will the packages always require the assumption that the rendering engine/library is glimmer. |
@ef4 should we leave this open still? |
This is still a good goal, but the details have likely changed since this was written and an updated proposal would be needed to move this forward. The crux of the issue is that to maintain correctness while using separate packages we really need reliable peer dependencies, and NPM clients are still pretty terrible at peer dependencies, though the exact ways in which they are good and bad are shifting. pnpm is currently the best at correctness, but if we want to lean heavily on that we'll need an RFC asking the community to all adopt pnpm, and that might be a tough sell for some companies. |
Rendered