-
-
Notifications
You must be signed in to change notification settings - Fork 54
Conversation
active/0000.prebuild-addon.md
Outdated
|
||
-Check if the `isDevelopingAddon` flag is not set | ||
-Check if the requested tree can be prebuilt (any of the default trees that can be prebuilt) use the prebuilt addon if it exists for the same target as the app | ||
-Finds the md5 checksum of the application target and forms a prebuiltdirectory name by appending checksum of target, addon version, tree name |
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.
prebuilt directory
Currently the implementation assumes that the trees to prebuild will be specified in package.json which will be changed in subsequent commit. ember-cli POC (WIP) Prebuild addon |
active/0000.prebuild-addon.md
Outdated
|
||
If the application is using the incorrect prebuilt addon, the application build will break | ||
|
||
-The latest version of target browser changes continuously hence the prebuilt directory might not necessarily be built for the latest version of the browser. But since current last version will always be a subset of future last versions the prebuilt directory will always be valid. |
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.
But since current last version will always be a subset of future last versions the prebuilt directory will always be valid.
This assertion is not correct. Features have been removed from browsers (eg. SharedArrayBuffer
due to Spectre).
You also assume that Babel / preset-env is infallible, and that the generated output is always correct. This is NOT the case. If a transpilation issue arises, it will no longer be fixed with an upstream update, but instead requires the ember addon to publish an update, though no addon code has a changed.
My comment from the meeting: Not sure about others, but I often go into node_modules to tweak random addon code. Whether I'm trying to diagnose an addon bug before submitting a PR, or just to add console logging. Then I restart my server and the new code is there. We should be aware that people do this and help them discover that this method will no longer work with prebuilt addons. It would be possible to detect this and do the right thing, but it would be complex. |
Meeting notes:
|
One concern is that there is almost certainly state/configuration other than the browser targets that influences the build. I think we need to design the prebuilt cache such that it can accomodate an arbitrarily rich summary of all the settings that influenced a particular bundle, and match those again when determining if there is a valid bundle in the cache. (Consider for example that addons are going to soon be gaining the ability to expose different behavior when used in classic app layout vs module unification layout. Or that Also, if we are focused on publishing prebuilt bundles inside addons, the more targets you support, the bigger your NPM packages get. I don't really think NPM is the best vehicle for distributing many targets worth of bundles. Where NPM itself confronts this same issue for native extensions, they don't bake all the prebuilt targets into the NPM package, they offload them to storage elsewhere. So I would rather emphasize the parts of this RFC that would enable shared, persistent build caching as the base primitive. If we focus on designing the format for the build cache that can be easily
we can then separate the question of where to store those caches and how to pick the set of targets. Maybe sometimes it will be fine to put cached builds inside npm packages. Maybe sometimes they could be separate hosting (like s3) controlled by addon authors. Maybe some companies will want to have their own shared caches that are used by all their developers -- the first person to build a new addon under a new target will do the full build and then update the shared cache for everyone else (automatically, as long as you flip a switch saying you want to share your results with the cache). |
While I understand the want to reduce build times I’m not quite sure the value of prebuilding beyond what broccoli or similar would already have in a warm cache/temp dir. As we begin tree shaking and possibly parallelizing builds this could become a possible source for conflicts or inconsistent results. Something we could do instead though is to better surface this cache for things like CI where a warm tmp directory may not be available. |
It is unclear to me after several reads where the responsibility for pre-building lives. It seems like addon authors need to ship (some/many/all) pre-built targets during NPM publish, but at the same time there is an addon for the app that handles pre-building there? And if addon and app targets don't match then what? This leaves me confused about what the benefit is. Will I most likely just be adding |
So after taking a while to let this sit in and getting some inspiration from #ember2018 posts, I think this is a fairly convoluted way around a problem. So there's a few painpoints that definitely do exist:
This seems like a way to cut down the initial build time, but it really adds a lot of complexity to projects and user land. Also spotting and debugging different compile targets could be really tricky since these errors could not be obvious as to what is causing the error. The solution to that would be to add a lot of complex target diff checking into Ember CLI which makes it harder to understand what CLI is doing (which is 👎 to me when the community wants to demystify and remove complexity). This would also mean that you're likely going to have to prebuild these addons for your app anyway because of differences in targets and babel configs. This said, I think the problem of addons build trees being active in file watching and intermediary files in the As far as I know right now addon broccoli trees are active during the entire app serve command. Something that could help with this is an option like The idea of an opt out would be tricky to manage but there are those who know a lot more about CLI and Broccoli internals that might be able to run with that idea or build on it. |
We already don’t watch addon trees by default. |
@ef4 it may depend on the addon, but from my experience most addons are watched for changes. I just went into one of my apps which has no config changed and changed a template from The file I changed was |
Huh, I guess my info is out of date. The code that makes the decision is here. I don't know the history fo that TODO comment. |
I agree that many people will change the code in node_modules directly. One way to handle this is to exclude the addon that you want to change from using this feature. It can be provided as an env variable or can be specified in package.json of the project (app/addon). The updated RFC explains this in detail. Let me know what you think about it. |
Both addons and app can prebuild.
The major benefit can be achieved in cold build if the prebuild is stored and reused. In our large example app the babel transpilation takes half the time and transpiling addons takes half of the babel time during cold build.
Cache key takes addon version (name, package.json, babel options, target browsers) into account. The 2 cases when the code will change but the version will not change is when the addon is symlinked or when the package.json has addon pointing to gitpath instead of version. These 2 cases are handled. Currently as a first step the idea is to let individual developers use this as part of their cold build.
With the new implementation there is no separate addon to prebuild. Right now as you said this behavior will be part of initial cold build or serve. It uses environment variable. We can decide on whether to use a flag or env variable. |
This should not be a source of conflict rather they should all co-exist with each other. Like how tree shaking will help in sitespeed, prebuild will help with build time.
Yes, It can be done if the prebuild is stored in a location where it can be fetched in CI as well.
Prebuild will generate a log file which will have information about the addon name, prebuild path, treeType etc. which can be used to check whether prebuild is being used and the location it fetches prebuild from. Likewise if there is an issue with prebuild of an addon we can clear the prebuild for that addon alone or exclude the prebuild for that addon.
That is a very good idea that can be explored. Let me know what you think about the updated RFC. |
Currently the cache key is determined by the following addon.name,
addon.pkg && Object.keys(addon.pkg).sort()
typeof addon.options.babel === 'function' ? addon.options.babel() : addon.options.babel,
addon.options['ember-cli-babel'],
targetBrowsers this can be enhanced to add more metadata to determine a valid configuration for the prebuild.
We are prebuilding only the addon, addon-test-support and templates tree of an addon. My understanding is they should impact only the app code and not these trees. Please correct me if am wrong.
Yes I agree with your idea about storing the prebuilt directories. The path will be made configurable so that the addon or the app can specify the location to store prebuilt directories. Be it npm or s3 or company repo. If no path is specified it can default to npm package. Currently as a first step the idea is to let individual developers use this as part of their cold build. |
@arthirm this all looks very good and I still think this is a good idea to pursue, right now we have much churn in this area:
It would make me nervous to commit to this until some of the above pieces have also landed. That being said, have done the research here is awesome. That way we can utilize it when we are ready. @arthirm that being said, one big question I have, is how does this work with babel-plugin-htmlbars-inline-precompile which is a default babel plugin, but also explicitly depends on the template compilter provided by that version of ember? I don't think this is an insurmountable problem, but does seem like a blocker until resolved. What solutions do you see? |
The simplest approach is to include the ember version as well in the cache key while generating a prebuild. While building the app, if the ember version of the app matches with the ember version used in the cache key then the prebuilt template tree can be used. Let me know if you think of any other approach. |
But the problem with associating ember version with the cache key is there may be many projects which wont be using the same ember version as the one used in prebuild. In those cases it will be less useful where it is better to prebuild templates from app. |
We are working on closing the ember-cli/rfcs repo in favor of using a single central RFC's repo for everything. This was laid out in https://emberjs.github.io/rfcs/0300-rfc-process-update.html. Sorry for the troubles, but would you mind reviewing to see if this is still something we need, and if so migrating this over to emberjs/rfcs? Thank you! |
This RFC is about
Prebuilding addons prior to building the ember app to reduce the application build time.
Below is the summary of Cold Build timings from
ember serve
by Prebuilding only the first level addons. (Not addons inside another addons/apps)New App
With prebuild - 1.5 secs (73% improvement)
Without prebuild - 5.7 secs
No of addons prebuilt - 7
No of addons visited - 29
Travis-Web
With prebuild - 57.3 secs (32% improvement)
Without prebuild - 84.5 secs
No of addons prebuilt - 36
No of addons visited - 69