-
-
Notifications
You must be signed in to change notification settings - Fork 54
Ember CLI: Production code stripping #50
Ember CLI: Production code stripping #50
Conversation
43f4094
to
855c04e
Compare
All calls to the methods of those that you mentioned get stripped out in a production build except for |
I don't believe that they are stripped from production, AFAIK the functions calls remain. They are no-ops though
|
Oh. In the documentation it sates
And for info it does not say that, just says |
I recently updated the |
I don't use it but I can see why others would. We could leave |
I never have either, but was just basing it off of the docs. However, looking at the code... /**
Display an info notice.
@method info
@private
*/
setDebugFunction('info', function info() {
Logger.info.apply(undefined, arguments);
}); it seems like it's treated the same. Just looks like the docs for that need to be updated. |
@webark - |
|
||
TODO: | ||
|
||
* [ ] Are all these functions already no-ops in production? If so, there are no obvious drawbacks |
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, all of the functions above are set to function() { }
by default:
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, updated
855c04e
to
8a40169
Compare
@rwjblue good to know. It looks like the docs need to be updated to reflect that. I might find out where that is and go and issue a PR. |
d3e11d7
to
17effe9
Compare
I believe this belongs being a feature of Ember proper once Ember itself is an addon, or as an official but stand alone addon, and not part of ember-cli. My reasoning is that ember-cli is increasingly not ember-specific, but this behavior is very specific to Ember apps. |
@runspired Perhaps other consumers of ember-cli would also benefit from the ability to configure what to strip from production builds? Only the configuration for ember builds needs to be ember specific |
@runspired Regardless of where it lives (officially sanctioned and bundled addon, core ember-cli) this is the right place to have the conversation. The question is almost "should addons be responsible for this themselves, or should ember-cli be a cool cat and have your back?" It can be built-in, a dep for ember-cli, or an individual dep for each addon that needs it. Since Ember is a future addon we have a way to think about handling it for Ember (note that this is one of a few build tasks for Ember itself which needs logic and will need some way to handle that when not being bundled as a holistic package). I don't feel particularly strongly about where it lives but tend toward including it as a dependency of ember-cli. This sort of behavior (if configurable) will be used across all future things similar to ember-cli. |
@GavinJoyce @nathanhammond if its abstract in a way that lots of addons can use it, and it just happens to be configured for Ember, that's much different than building in something that strips out code that's closely tied to Ember. I'm all for the abstract thing being in ember-cli :) |
* [babel-plugin-filter-imports](https://github.com/ember-cli/babel-plugin-filter-imports) with added support for defining module functions for removal ([spike here](https://github.com/GavinJoyce/babel-plugin-filter-imports/pull/1)) | ||
* a new babel plugin which works similarly to `babel-plugin-filter-imports` | ||
|
||
For consistency, this plugin should also be used in Ember Data and other Ember projects which would benefit from the reduced size. |
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 detailed design should include how this works with addons, and nested addons.
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.
👍
@krisselden this is related to your thoughts/ideas you should likely provide feedback. |
One scary side-effect of not stripping So even though the functions are implemented as no-ops in production builds, depending on what arguments that are slow to evaluate or have side-effects could cause either performance problems or bugs when run in production. Before reading this RFC, I'd been operating under the assumption that As a work around, we should perhaps encourage anyone using
Short of AST-hackery or C-style macros, an Until this is implemented, perhaps we should encourage projects like ember-data to wrap their debug code in such a guard. Aside: A more generic mechanism could be used for ember-cli compile time build stripping. For example, code that exists only to provide compatibility with older versions of ember could be stripped when included in newer versions (kinda like macros in C):
Thoughts? |
@les2 yup, we agree / are aware. Would love to see this land |
@les2 I've got an implementation of this RFC which I'll extract to an addon soon. I'll post again when it's available |
I just did a fresh read through, and think we should also publicly expose helpers similar to the ones used inside Ember itself for testing around assertions (in Ember we use emberjs/ember-dev to provide Other than that, I am pretty happy with this moving forward... |
@@ -28,17 +28,23 @@ A Babel plugin will execute the removal of these function calls. It will either | |||
* [babel-plugin-filter-imports](https://github.com/ember-cli/babel-plugin-filter-imports) with added support for defining module functions for removal ([spike here](https://github.com/GavinJoyce/babel-plugin-filter-imports/pull/1)) | |||
* a new babel plugin which works similarly to `babel-plugin-filter-imports` | |||
|
|||
For consistency, this plugin should also be used in Ember Data and other Ember projects which would benefit from the reduced size. | |||
The babel plugin will affect the code of the current app or addon only and won't affect code in child or grandchild addons. As this change becomes part of the default ember-cli configuration, addons will adopt the code stripping as they upgrade to newer ember-cli versions. |
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.
@stefanpenner @rwjblue please review this change to the code stripping RFC
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.
Yep, this seems like exactly what we discussed.
Great, shipping this to FCP today! |
I've written a few babel5/babel6 plugins to do this sort of production code stripping in multiple addons now. I would be very willing to help build an abstract version to land this RFC. :) |
Definitely in favor of this. @runspired, is there an addon I can use to have this happen in my app today? |
@runspired Nice one. I'm planning to work on an experimental implementation of this later today, I'll post the repo when there is something in it. @Gaurav0 This should be relatively easy to build, I expect that there will be something to try out tomorrow. I'm hoping to run the early experimental addon in Intercom in production later this week. |
* [`Ember.deprecate`](http://emberjs.com/api/#method_deprecate) | ||
* [`Ember.info`](http://emberjs.com/api/#method_info) | ||
* [`Ember.runInDebug`](http://emberjs.com/api/#method_runInDebug) | ||
* [`Ember.warn`](http://emberjs.com/api/#method_warn) |
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.
is it wise to strip warn? if i were new to ember i would assume that info and "higher" were not stripped.
edit: the wip implementation is configurable so this concern is no longer relevant.
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.
@les2 Also both warn
and info
are already no-op in production builds. Stripping them don't change any behavior.
The idea of log level here is mostly related to how these things appear in the JS console in browsers, not to what build of ember that function emits in.
|
||
# Unresolved questions | ||
|
||
* [ ] Should we allow the stripping configuration to be overridden in `ember-cli-build.js`? If so, what should the API be? |
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.
for info and debug statements, it would be useful to configure them to not be stripped per add-on.
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, this should be configurable. The API should require you to identify source (global, module), and then the corresponding keypath. In other words, enough to feed it directly into Babel. The core rules should be implemented in this manner.
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 about:
{
removals: [
{
module: 'ember', //eg. import Em from 'ember';
paths: [
'assert', //Em.assert will be removed
'debug', //Em.debug will be removed
'a.b.c' //Em.a.b.c will be removed
]
}, {
global: 'Ember',
paths: [
'deprecate' //Ember.deprecate will be removed
]
}, {
paths: [
'console.log' //console.log will be removed
]
}
]
}
I'd like to find a better key name than removals
.
A Babel plugin will execute the removal of these function calls. It will either be: | ||
|
||
* [babel-plugin-filter-imports](https://github.com/ember-cli/babel-plugin-filter-imports) with added support for defining module functions for removal ([spike here](https://github.com/GavinJoyce/babel-plugin-filter-imports/pull/1)) | ||
* a new babel plugin which works similarly to `babel-plugin-filter-imports` |
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.
note that there is also https://github.com/azu/babel-plugin-strip-function-call, but it is Babel 6+
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. This one doesn't seem to handle import statements, but it is useful for reference
WIP experimental implementation of the babel transform: https://github.com/GavinJoyce/babel-plugin-remove-functions |
Perhaps we should also enable by default on test builds (or perhaps only disabled on development builds)? Any side effects that removing the code might introduce on production would also be tested |
I don't think so. The main reason is that you want all of the helpful assertions/deprecations to fire in tests (so you can fix them and have a fighting chance at understanding what is going on). I have long advocated that folks should always be running their apps tests against production builds in CI. Typically I suggest a matrix setup where you run both |
* [babel-plugin-filter-imports](https://github.com/ember-cli/babel-plugin-filter-imports) with added support for defining module functions for removal ([spike here](https://github.com/GavinJoyce/babel-plugin-filter-imports/pull/1)) | ||
* a new babel plugin which works similarly to `babel-plugin-filter-imports` | ||
|
||
The babel plugin will affect the code of the current app or addon only and won't affect code in child or grandchild addons. As this change becomes part of the default ember-cli configuration, addons will adopt the code stripping as they upgrade to newer ember-cli versions. |
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 are you intending to accomplish this? Are you intending to register it as a preprocessor? This feels relatively tricky to do right.
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.
Pretty easy (stolen from ember-cli-htmlbars-inline-precompile):
included: function(app) {
this._super.included.apply(this, arguments);
app.options = app.options || {};
app.options.babel = app.options.babel || {};
app.options.babel.plugins = app.options.babel.plugins || [];
if (!this._registeredWithBabel) {
app.options.babel.plugins.push(require('./some-path-to-thing');
this._registeredWithBabel = true;
}
}
When added as a dependency, this will add to its including project's or addon's babel processing (which is independent at each layer).
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's pretty clever, actually. I like it.
|
||
# Unresolved questions | ||
|
||
* [ ] Should we allow the stripping configuration to be overridden in `ember-cli-build.js`? If so, what should the API be? |
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, this should be configurable. The API should require you to identify source (global, module), and then the corresponding keypath. In other words, enough to feed it directly into Babel. The core rules should be implemented in this manner.
# Unresolved questions | ||
|
||
* [ ] Should we allow the stripping configuration to be overridden in `ember-cli-build.js`? If so, what should the API be? | ||
* [ ] Related to above, should we allow the feature to be disabled? |
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.
Making this possible makes for annoying partial config in ember-cli-build.js (which things to strip) and in environment.js (which environments to strip in) and will be a source of numerous user-error bugs.
Since we will ship with defaults of some sort we do need to provide a way to modify/clobber those, and whatever that method is will be the way to turn it off (or just remove the addon). (Keeps the API cleaner.)
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.
Disabling should be on a per-addon/project basis, by simply removing the addon.
Cleanup things I'd like to make a bit more clear but don't change anything:
|
af60ace
to
7362ad0
Compare
@nathanhammond thanks, I've completed those tasks. I've also added an example of possible configuration |
7362ad0
to
6e4cdbe
Compare
6e4cdbe
to
18dc017
Compare
Because of the updates regarding configuration we're restarting FCP. Barring additional commentary this No meeting on November 24 because of US Thanksgiving. December 1. |
No further feedback, we're accepting this RFC and intending to land an implementation. Thank you @GavinJoyce for instigating this and bring it to completion! |
Rendered
some previous discussion