在src目录下新建一个math.js文件,现在目录结构如下:
src/math.js
export const add = (a, b) => {
console.log( a + b )
}
export const minus = (a, b) => {
console.log( a - b )
}
src/index.js
import { add } from './math.js'
add(1, 2)
现在让我们运行npx webpack
,并检查输出的 bundle:
dist/app.bundle.js
/***/ "./src/math.js":
/*!*********************!*\
!*** ./src/math.js ***!
\*********************/
/*! exports provided: add, minus */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "add", function() { return add; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "minus", function() { return minus; });
const add = (a, b) => {
console.log(a + b);
};
const minus = (a, b) => {
console.log(a - b);
};
/***/ })
/******/ });
注意到math.js文件中minus并没有被导入,但是,它仍然被包含在 bundle 中。
理想的打包方式应该是:引入什么打包什么。
注: Tree Shaking 只支持ES Module, commonjs就不行。
ES Module 和commonjs的区别:
-ES Module静态引入, 编译时引入
-commonjs动态引入, 执行时引入
-只有ES Module才能静态分析, 实现tree-shaking
接下来看Tree Shaking的配置
development模式下默认没有Tree Shaking功能, devtool要设置为: cheap-module-eval-source-map。
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const webpack = require('webpack')
module.exports = {
//默认没有Tree Shaking功能, devtool: cheap-module-eval-source-map
mode: 'development',
devtool: 'cheap-module-eval-source-map',
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true,
hotOnly: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader', //babel-loader:babel和webpack中间的桥梁
options: {
"presets": [
[
//es6=>es5
"@babel/preset-env", {
"targets": {
// "edge": "17",
// "firefox": "60",
// "chrome": "67",
"safari": "11.1", //以上版本已经支持es6,不需要再做es6=>es5
},
useBuiltIns: 'usage'
}
],
"@babel/preset-react", //转化react代码
],
// "plugins": [
// [
// "@babel/plugin-transform-runtime",
// {
// //安装: npm install --save @babel/runtime-corejs2
// "corejs": 2,
// "helpers": true,
// "regenerator": true,
// "useESModules": false,
// }
// ]
// ]
}
},
{
test:/\.css$/,
use: [
'style-loader',
'css-loader'
]
},
]
},
entry: {
app: './src/index.js',
// print: './src/print.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
//publicPath也会在服务器脚本用到,确保资源能够在 http://localhost:3000下正确访问
publicPath: '/'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin() //要先引入webpack,是webpack自带的插件
],
//Tree Shaking配置项
optimization: {
usedExports: true
}
}
还需要在package.json写一个配置项:
{
"name": "lesson0523_new",
"sideEffects": false
}
当在index.js文件中引入了一个样式表style.css即import './style.css'
,但样式表显然没有导出任何内容就会被摇晃树摇晃掉。
如果你的代码确实有一些副作用,那么可以改为提供一个数组:
{
"name": "lesson0523_new",
"sideEffects": ["*.css"]
}
再次运行npx webpack
并检查输出的 bundle:
而当production模式下,则有Tree Shaking功能,不需要配置项,但要修改devtool: cheap-module-source-map
webpack.config.js:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const webpack = require('webpack')
module.exports = {
//默认没有Tree Shaking功能, devtool: cheap-module-eval-source-map
// mode: 'development',
mode: 'production',
// devtool: 'cheap-module-eval-source-map',
devtool: 'cheap-module-source-map',
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true,
hotOnly: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader', //babel-loader:babel和webpack中间的桥梁
options: {
"presets": [
[
//es6=>es5
"@babel/preset-env", {
"targets": {
// "edge": "17",
// "firefox": "60",
// "chrome": "67",
"safari": "11.1", //以上版本已经支持es6,不需要再做es6=>es5
},
useBuiltIns: 'usage'
}
],
"@babel/preset-react", //转化react代码
],
// "plugins": [
// [
// "@babel/plugin-transform-runtime",
// {
// //安装: npm install --save @babel/runtime-corejs2
// "corejs": 2,
// "helpers": true,
// "regenerator": true,
// "useESModules": false,
// }
// ]
// ]
}
},
{
test:/\.css$/,
use: [
'style-loader',
'css-loader'
]
},
]
},
entry: {
app: './src/index.js',
// print: './src/print.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
//publicPath也会在服务器脚本用到,确保资源能够在 http://localhost:3000下正确访问
publicPath: '/'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin() //要先引入webpack,是webpack自带的插件
],
//Tree Shaking配置项
// optimization: {
// usedExports: true
// }
}
再次运行npx webpack
,再次查看bundle.js文件minus已经剔除掉了。
打包生成线上代码,已经把minus剔除掉了,说明Tree Shaking功能生效。