webpack-demo|- package.json|- webpack.config.js|- server.js|- DEV-server.js|- /dist|- /src|- data.xml|- icon.png+|- style.css|- my-font.woff|- my-font.woff2|- print.js|- index.js+ |- math.js|- /node_modules
// math.jsexport function square(x) {return x * x;}export function cube(x) {return x * x * x;}
// index.jsimport _ from 'lodash';import './style.css';import Icon from './icon.svg';import Data from './data.xml';import printMe from './print.js';import { cube } from './math.js';function componentPre() {let element = document.createElement('pre');element.innerHTML = ['Hello webpack!','5 cubed is equal to ' + cube(5)].join('\n\n');element.classList.add('hello');var myIcon = new Image();myIcon.src = Icon;element.appendChild(myIcon);var btn = document.createElement('button');btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe;element.appendChild(btn);console.log(Data);return element;}function component() {let element = document.createElement('div');element.innerHTML = _.join(['Hello', 'webpack'], ' ');element.classList.add('hello');var myIcon = new Image();myIcon.src = Icon;element.appendChild(myIcon);var btn = document.createElement('button');btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe;element.appendChild(btn);console.log(Data);return element;}// document.body.appendChild(component());let element = componentPre(); // Store the element to re-render on print.js changesdocument.body.appendChild(element);if (module.hot) {module.hot.accept('./print.js', function () {console.log('Accepting the updated printMe module!');document.body.removeChild(element);element = componentPre(); // Re-render the "component" to update the click handlerdocument.body.appendChild(element);})}
Tree Shaking
webpack 设置 tree shaking 需要在package.json 加上 sideEffects: false 这个,指明无副作用,
还需要设置 webpack.config.js 设置 mode: ‘production’
实验,实际 package.json 加上 sideEffects: false,并没有什么卵用,只要设置 mode: ‘production’ 就会做tree shaking,但是有多少效果就不清楚了。
在使用 tree shaking 时必须有 ModuleConcatenationPlugin 的支持,您可以通过设置配置项 mode: “production” 以启用它。如果您没有如此做,请记得手动引入 ModuleConcatenationPlugin。
{"name": "webpackDemo","sideEffects": false,"version": "1.0.0","description": "","private": true,"main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","watch": "webpack --watch","build": "webpack","start": "webpack-dev-server --open","server": "node server.js"},}
请注意,任何导入的文件都会受到树抖动的影响。这意味着如果您css-loader在项目中使用类似的东西并导入CSS文件,则需要将其添加到副作用列表中,以便在生产模式下不会无意中将其删除:
// package.json或{"name": "webpackDemo","sideEffects": [ // 有一些内容虽然没有被使用,但是可能是关联性,所以不能被优化掉。"./src/some-side-effectful-file.js","*.css"],"version": "1.0.0","description": "","private": true,"main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","watch": "webpack --watch","build": "webpack","start": "webpack-dev-server --open","server": "node server.js"},}
mode: ‘production’,可以将环境切换为生产环境,代码会自动被压缩打包。
optimization: {usedExports: true // 标记去掉未使用方法},
所以,我们所学到的是,为了利用树木摇晃,你必须……
- 使用ES2015模块语法(即
import和export)。 - 确保没有编译器将您的ES2015模块语法转换为CommonJS模块(这是流行的Babel预设@ babel / preset-env的默认行为 - 有关详细信息,请参阅文档)。
- 将
"sideEffects"属性添加到项目的package.json文件中。 - 使用配置选项可启用各种优化,包括缩小和树抖动。production
mode
您可以将您的应用程序想象成一棵树。您实际使用的源代码和库代表树的绿色活树。死码代表秋天消耗的棕色枯叶。为了摆脱枯叶,你必须摇动树,使它们掉下来。
解释 tree shaking 和 sideEffects
sideEffects 和 usedExports(更多被认为是 tree shaking)是两种不同的优化方式。
sideEffects 更为有效 是因为它允许跳过整个模块/文件和整个文件子树。
usedExports 依赖于 terser 去检测语句中的副作用。它是一个 JavaScript 任务而且没有像 sideEffects 一样简单直接。而且它不能跳转子树/依赖由于细则中说副作用需要被评估。尽管导出函数能运作如常,但 React 框架的高阶函数(HOC)在这种情况下是会出问题的。
