-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Pure annotation in downlevel emits #5632
Comments
Hey @BlackSonic! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
Hey @BlackSonic, thanks for the issue! It looks like you already made this issue in #3821 😄 ? We should close one of them |
@hzoo I would close the older one as this one is more detailed and links to UglifyJS resources. |
@BlackSonic Can you try out this naïve babel plugin? It appears to work well enough to drop unused down-levelled classes.
|
@kzc It works perfectly with your plugin! |
/cc @sokra @TheLarkInn |
Static class properties prevent unused ES5 generated classes from being dropped by uglify due to the fact that they are generated outside the IIFE:
With the following (admittedly awful and likely incorrect) proof-of-concept hack, these static class properties will be generated within the IIFE so that uglify will be able to drop the generated class: diff -u -r node_modules.orig node_modules
diff -u -r node_modules.orig/babel-plugin-transform-class-properties/lib/index.js node_modules/babel-plugin-transform-class-properties/lib/index.js
--- node_modules.orig/babel-plugin-transform-class-properties/lib/index.js 2017-05-05 13:53:24.000000000 -0400
node_modules/babel-plugin-transform-class-properties/lib/index.js 2017-05-05 13:37:35.000000000 -0400
@@ -221,7 221,7 @@
}
}
- path.insertAfter(nodes);
path.node.__static_props = nodes;
},
ArrowFunctionExpression: function ArrowFunctionExpression(path) {
var classExp = path.get("body");
diff -u -r node_modules.orig/babel-plugin-transform-es2015-classes/lib/vanilla.js node_modules/babel-plugin-transform-es2015-classes/lib/vanilla.js
--- node_modules.orig/babel-plugin-transform-es2015-classes/lib/vanilla.js 2017-05-05 13:53:29.000000000 -0400
node_modules/babel-plugin-transform-es2015-classes/lib/vanilla.js 2017-05-05 13:56:04.000000000 -0400
@@ -152,6 152,11 @@
if (body.length === 1) return t.toExpression(body[0]);
}
for (var i = 0, arr = this.path.node.__static_props; arr && i < arr.length; i) {
body.push(arr[i]);
}
this.path.node.__static_props = null;
body.push(t.returnStatement(this.classRef));
var container = t.functionExpression(null, closureParams, t.blockStatement(body)); With the hacked version of babel notice that the generated static properties were moved into the IIFE:
which allows uglify to drop the unused annotated class IIFEs:
|
There is also the common use-case when folks are using react stateless components, so no class expressions. They can be made/transformed into it an IIFE to include random stuff like const Comp = ({ foo = 'bar' }) => <span>{foo}</span>;
Comp.displayName = 'Comp';
Comp.propTypes = { foo: PropTypes.string }; // Eliminated by using flowTypes instead
export default Comp; to something like const Comp = function(){
const Comp = ({ foo = 'bar' }) => <span>{foo}</span>;
Comp.displayName = 'Comp';
Comp.propTypes = { foo: PropTypes.string }; // Eliminated by using flowTypes instead
return Comp;
}();
export default Comp; But the above also seems to have side effects and uglifyJS doesn't seem to eliminate, I had to manually add |
@priyajeet dont use explicit The only valid use case for const wrappedDisplayName = WrappedComponent.displayName || WrappedComponent.name || 'Unknown' So it will gracefully use inferred name for regular components. Still the problem persists because of the @hzoo |
|
@taion hmm, I thin that would be better served by an integration between devtools and sourcemaps |
PR is #6209 |
Feature request
Minifiers like Uglify try to remove dead code from minified builds.
To completely remove a declaration, they have to prove that it is side-effect free.
Unfortunately in JS this is often not possible as pretty much anything can have arbitrary effects.
An important issue is that ES5 emit for
class
can't easily be determined to be side-effect free.As a result, tree-shaking is ineffective. In simple words: no class is removed from the output, even if it is never used.
A very simple solution could be to have a hint for the minifier, inside a special comment.
If the emit added a
/*#__PURE__*/
comment at the beginning of ES5 classes it could easily be detected and removed by Uglify.This is an important enhancement that can dramatically reduce the size of unused code, especially in large libraries.
Uglify|JS already supports this annotation: mishoo/UglifyJS#1448
Original UglifyJS discussion: mishoo/UglifyJS#1261
For reference, implementation details are here: mishoo/UglifyJS@1e51586
The issue was originally raised at Webpack: webpack/webpack#2867
The text was updated successfully, but these errors were encountered: