We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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
tree-shaking, 字面的上意思是摇晃树,用来在ES Module中, 剔除不需要引入的模块的, 这是一个从webpack2.0`的时候就支持的功能, 但是支持的程度不尽人意.
tree-shaking
具体的问题是babel, uglifyJs会有副作用,具体请看你的Tree-Shaking并没什么卵用, 非常nice的一篇文章.
文章里面的想表达的意思, 因为在babel和uglifyJs的打包之后, webpack很难判断依赖的代码或者项目的代码,是否具有副作用, 或者说打包后都产生了副作用,副作用包括了属性的获取,对象属性的编辑, 或其他影响了全局变量或者方法的操作. 比如赋值属性obj2 = obj1; obj2.prototype.toString=fn等等.因为修改了obj1的方法,这就是会产生副作用. babel实现一个Polyfill的Class, 会给这个变量使用defineProperty定义属性,这也算是副作用的一种.
obj2 = obj1; obj2.prototype.toString=fn
Polyfill
Class
defineProperty
正是以上的原因,因为产生了副作用, 所以导致了webpack用的uglifyJs打包出来的效果和我们相差甚远.
因此, 在webpack4.0之后, 使用ES Module的terser-webpack-plugin进行打包, terser-webpack-plugin包其实uglifyJs-es的一个fork, 支持ES Module 语法的压缩处理.
terser-webpack-plugin
uglifyJs-es
下面是sideEffects:false的打包效果, 以webpack2.x/webpack3.x和 webpack4.x的打包版本进行对比.
sideEffects:false
// webpack 2.x "dependencies": { "babel-loader": "6.2", "uglifyjs-webpack-plugin": "1.1.1", "webpack": "2.4", "babel-core": "^6.26.3", "babel-preset-es2015": "^6.24.1", "webpack-cli": "^3.3.9" } // webpack 3.x "dependencies": { "babel-core": "^6.26.3", "babel-loader": "7", "babel-preset-env": "^1.7.0", "uglifyjs-webpack-plugin": "1", "webpack": "3" }
/* index.js */ import { B } from './test'; const b = new B('bbbbbbbbbbbb').getName(); console.log(b); // test.js export class A { constructor() { this.name = 'AAAAAAAAAAAAAA'; } getName() { return this.name; } } export class B { constructor({ val }) { this.name = 'constructor bbbbbbbbbbb'; this.val = val; } getName() { console.log(this.val); return this.val; } }
tree-shaking如果是理想的话, 可以修剪掉test.js#class A.
test.js#class A
另外注意的是:webpack2.x/webpack3.x使用tree-shaking是有条件的
uglifyjs
babel
import {xxx} from xxx
uglifyJS
所以因为这个问题, uglifyJs有个issue讨论了添加tree-shaking的副作用, 所有出现了/@PURE/.
uglifyJs
{ optimization: { sideEffects: true | false, /*生产模式下默认开启,其他模式不开启。 如果开启, 那么就会以package.json#sideEffect里面的内容为参考对象*/ } }
package.json#sideEffect的值true|false|[ignore files], 默认为false, 在项目开启tree-shaking的时候,常常需要把这个值设置为忽略我们的sass 或者less的代码, 否则会影响打包的css结果.
package.json#sideEffect
true|false|[ignore files]
比如:
{ "sideEffects":['./sass/index.scss'] }
指定特定的文件具有副作用, 进而忽略对应文件的tree-shaking, 如果想要关注更多的tree-shaking打包细节,请看terser.
tree-shaking是代码优化中的有效而且重要的一环, 今天的文章算是一个抛转引玉, 期待社区出现关于terser解读tree-shaking的深度好文.
terser
https://github.com/webpack/webpack/tree/master/examples/side-effects https://juejin.im/post/5b4ff9ece51d45190c18bb65 https://segmentfault.com/q/1010000018871965 https://zhuanlan.zhihu.com/p/32831172
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
tree-shaking
, 字面的上意思是摇晃树,用来在ES Module中, 剔除不需要引入的模块的, 这是一个从webpack2.0`的时候就支持的功能, 但是支持的程度不尽人意.文章里面的想表达的意思, 因为在babel和uglifyJs的打包之后, webpack很难判断依赖的代码或者项目的代码,是否具有副作用, 或者说打包后都产生了副作用,副作用包括了属性的获取,对象属性的编辑, 或其他影响了全局变量或者方法的操作. 比如赋值属性
obj2 = obj1; obj2.prototype.toString=fn
等等.因为修改了obj1的方法,这就是会产生副作用. babel实现一个Polyfill
的Class
, 会给这个变量使用defineProperty
定义属性,这也算是副作用的一种.正是以上的原因,因为产生了副作用, 所以导致了webpack用的uglifyJs打包出来的效果和我们相差甚远.
因此, 在webpack4.0之后, 使用ES Module的
terser-webpack-plugin
进行打包,terser-webpack-plugin
包其实uglifyJs-es
的一个fork, 支持ES Module 语法的压缩处理.sideEffects:false 的打包效果
下面是
sideEffects:false
的打包效果, 以webpack2.x/webpack3.x和 webpack4.x的打包版本进行对比.在webpack2.x, webpack3.x中使用的是环境
tree-shaking
如果是理想的话, 可以修剪掉test.js#class A
.另外注意的是:webpack2.x/webpack3.x使用
tree-shaking
是有条件的uglifyjs
打包压缩babel
的preset-env#module:false, 设置忽略ES Module代码import {xxx} from xxx
的方式加载模块代码说白了还是上面的谈到的问题, tree-shaking完全由
uglifyJS
来做, 那么他对副作用的判断和决定什么时候进行tree-shaking
, 是说不准的, 而在babel
打包出来的内容本身就具有副作用的.所以因为这个问题,
uglifyJs
有个issue讨论了添加tree-shaking的副作用, 所有出现了/@PURE/.webpack2.x,webpack3.x
webpack4.x
用webpack4.x打包出来的就已经tree-shaking掉了不用到的类class A, 而同样的配置, 在webpack2.x, webpack3.x中是效果不大的, 特别在IIFE的情况下, uglifyJs的tree-shaking难以工作.
optimize#sideEffects
package.json#sideEffect
的值true|false|[ignore files]
, 默认为false, 在项目开启tree-shaking的时候,常常需要把这个值设置为忽略我们的sass 或者less的代码, 否则会影响打包的css结果.比如:
指定特定的文件具有副作用, 进而忽略对应文件的
tree-shaking
, 如果想要关注更多的tree-shaking
打包细节,请看terser.总结
tree-shaking
是代码优化中的有效而且重要的一环, 今天的文章算是一个抛转引玉, 期待社区出现关于terser
解读tree-shaking
的深度好文.参考
The text was updated successfully, but these errors were encountered: