-
-
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
Ember CLI build pipeline #578
Conversation
As written, I find the motivation section less than compelling. This does not mean I do not support your proposal, rather that it needs to be improved with specific use cases and answering more questions.
This is not true. See Ember Twiddle's ember-cli-build.js to see how one can affect the final build output without using the treeFor* apis. This should be documented, but never has been. Please explain why this is not enough.
This may be more a documentation problem and a lack of tutorials than an issue with creating addons. Having experience in this, I find the process easy thanks to the available addon blueprint. Please explain why having these hooks allow more flexibility and control. Add specific use cases where using an addon is burdensome.
The
ember-cli, like broccoli itself, should do nothing without addons. To the extent that it does, IMO that logic should be moved to addons, because ember-cli can be used to build anything, not just ember apps.
Please explain why the
Please explain why this in particular is a maintenance nightmare. We've been doing this for over 6 years. |
Thanks for the detailed feedback @Gaurav0! I'll respond to some of your feedback here before updating the RFC text, if that's ok.
I suppose it's possible, but under-documented. I've been told in Discord that an Addon is the "right" way to add to the build, and I should not try to mess with the ember-cli-build.js file too much. This is why I said addons are the only "supported way". It would be a good step forward to improve documentation around the
We have an NPM module fetches translations. This module is used in non-Ember contexts, so we wrap it in an Addon for Ember. If we need to make a change to this module, it means making 3 PRs and 2 publishes in a very specific order. Without the middleman, it could be 2 PRs and 1 publish. We have a surprising number of addons whose only job is to do this kind of wrapping.
I'm not sure I agree with this, but the main driver is that any system should have a story for the simplest possible use case. If "plugin everything" is the direction to go, addons should be simplified and taught progressively, starting from a single file, and that's what the blueprints should output also. Even so, I think the final developer experience would look like this, making it possible to load and run build time code without understanding the whole system. const allAddons = require('ember-find-and-load-addons')();
const someFunctionality = require('third-party-lib');
return new EmberApp({
addons(env) {
return [
someFunctionality(),
...allAddons
]
}
}
app.toTree(); |
It's not underdocumented, it's not documented at all. :) Using addons is indeed the more supported way. Using the treeFor* hooks. I think we need some api here and replicating the existing treeFor* hooks may not be the best api, as these are pretty opaque and still require knowledge of broccoli. Again, it would help to show a specific use case in your motivation section, explain why treeFor* hooks would help. With a use case to discuss, we can demonstrate why this is necessary.
This is an excellent explanation. Just explain why you can't use an in repo addon or monorepo here.
I completely agree. ember-cli has traditionally been underdocumented and has too much Ember specific stuff in it. I'm not sure anyone has ever written a decent tutorial for using ember-cli outside of Ember. There are no blueprints for that use case. The hooks have never been perfect, so FastBoot, Engines, and Module Unification specific code has ended up in ember-cli. That original vision has not been kept. |
Yes, love it, totally in support of it. One question that I think needs answering has to do with the ordering. Addons can use So, my questions are:
I don't really have a good idea of the answer to (1) -- probably depends on what we think are the most common use cases for this functionality. For (2) I think I'd propose that we just add |
Currently, the only supported way to affect the Broccoli tree during build time is by hooking into | ||
the `treeFor*` APIs provided by addons. Developers that want to use these APIs are forced to develop | ||
an addon or in-repo addon. This is problematic for a few reasons: |
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.
Hmm, this doesn't seem quite correct. You can customize the default trees by passing options to new EmberApp()
like this:
let app = new EmberApp(defaults, {
trees: {
app: buildCustomAppTree(),
}
});
The default implementation could be thought of as:
let app = new EmberApp(defaults, {
trees: {
app: 'app',
tests: 'tests',
vendor: fs.existsSync('vendor') ? 'vendor' : null,
}
});
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.
Whlle this is true, it is not, to my knowledge, documented anywhere and may not even be public api.
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.
Thanks for the pointer, @rwjblue, I didn't know about that. Reference for future: https://github.com/ember-cli/ember-cli/blob/v3.18.0/lib/broccoli/ember-app.js#L319-L327
The proposal is to add additional trees, similar to what you do with addons, rather than having to start from scratch with a completely custom trees.
## Detailed design | ||
|
||
The high level of Ember application build looks like this: | ||
|
||
```js | ||
const app new EmberApp(defaults, {}); | ||
return app.toTree(); | ||
``` | ||
|
||
The `toTree()` method on the Application is responsible for gathering modules from the app | ||
and addons and outputing the `vendor.js` and an `app.js` file. In addition to creating the final bundle, | ||
it also runs the `treeFor` hooks from addons. It would be possible to add functionality to refactor | ||
this into also running `treeFor` hooks on the `EmberApp` instance itself. |
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 don't fully understand the proposal here, can you update this section to add more details about the design being proposed?
Are you suggesting adding something like:
let app = new EmberApp(defaults, {
treeFor(type, tree) {
if (type === 'app') {
return myCustomAppTree();
}
return tree;
}
});
?
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 did some more code reading and it looks like treeFor
and treeFor<Type>
are pretty different actually. The former is a blank slate, the latter receives the "implicit tree" (my name) from the addon's directory structure. That kind of makes it like a post processing hook.
I've updated the design section to explicitly say that we should add the treeFor<Type>
variants and what it should receive as an argument.
@bendemboski I've updated to answer your questions. I think the app variants of the hooks should run after addon hooks. Changing that order would require passing in a totally custom tree to |
Could others from the CLI team weigh in as well? @kategengler @kellyselden @kratiahuja @twokul Tagging @ef4 as well since embroider is a big part of the equation in CLI world right now. |
This RFC is in direct conflict with the embroider RFC. It would move Ember in exactly the opposite direction, toward more places where arbitrary code can generate arbitrary code. I want to emphasize strongly why the embroider RFC is structured as a package format specification and not a build pipeline description: you get portability and stability by specifying what, not how. This RFC is entirely in terms of "how" and not "what". I would be happy to look over the underlying use cases for which you wish you had these hooks. The intention is that all of them should be doable using the macro system, and that should be much easier for developers to read and write than being force to drop down to the broccoli level. |
@ef4 that's great to know, thanks for chiming in. In the most simplistic terms, my position is that many ember addons should not need to exist, because they simply call a function at the right time. There is no need to ship a package that does this, especially if the function is also shipped in its own package. Just to make sure we're on the same page, would you agree that today, "describing what" is not a reality, because addons can also only describe the "how", when it comes to the In any case, the salient question regarding the conflict here comes back to "when is embroider actually going to be viable?" Nobody can/wants to commit to an answer, of course, but under this light, is there any incremental progress we can make while we wait? |
The two use cases I would want this for are in https://github.com/ilios/frontend/tree/master/lib as in-repo addons:
I assume these keep working with in-repo addons in embroiderer? By the entire in-repo addon setup is kind of a weird edge case that doesn't seem to fit. Maybe embroider can do this another way? My understanding of the process is entirely at the addon level (at best). |
Yes, this is exactly what the macro system is for.
Now, I'm not trying to claim it's "done", because we still need better documentation and teaching materials so people can see how to plug the pieces together. But the pieces have been written and heavily tested for quite a while already. This is not far-future capability, this is today's capability. |
@jrjohnson both of your examples use Embroider doesn't have a super strong opinion about Your custom |
Oh interesting. So are these the appropriate next steps?
(Could the rest of the CLI core team weight in on this also?) |
Deprecation is premature. It would generate a ton of noise for app authors
that isn’t actionable.
I think the next step is getting the resources (docs, examples, and
supporting utilities) for addon authors into a complete state. That will
let them begin doing things the new way.
…On Fri, Jun 12, 2020 at 4:57 PM Mehul Kar ***@***.***> wrote:
@embroider/macros -- the part of Embroider that replaces custom broccoli
hooks -- is already supported in the current stable Ember release, because
it's implemented as an addon and works correctly under both the stock
ember-cli build pipeline and the full Embroider build pipeline
Oh interesting. So are these the appropriate next steps?
1. RFC to deprecate treeFor hooks
2. Ember CLI guides for using @embroider/macros
Could the rest of the CLI core team weight in on that?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#578 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACN6MUHHA7WVWE7MHGC453RWKJERANCNFSM4KFN6FEQ>
.
|
@jenweber @locks @amyrlam @mansona (as well as others from learning team), would you be open to adding a section to the CLI guides about this? (and will that require another RFC?) I can do the research and write the docs. |
I don't think writing guides for the macro system would require a new RFC since the system is described in https://github.com/emberjs/rfcs/blob/master/text/0507-embroider-v2-package-format.md |
The above discussion opens several action items for alternative solution to this RFC and embroider is far more mature now than when this was opened, so I'm closing. |
Rendered