Webpack
Tree Shaking
作用是当引入一个模块时,不会引入模块全部代码,只引入需要的部分代码,Tree Shaking只支持ES Module,不支持CommonJS模块方式。
例如只引入match.js的add方法
// match.js
export function add(a, b) {
return a + b;
}
export function minus(a, b) {
return a - b;
}
// index.js
import { add } from ‘./math‘;
webpack配置
// webpack.config.js 生产环境
module.exports = {
mode: ‘production‘,
devtool: ‘cheap-module-source-map‘,
}
// webpack.config.js 开发环境
module.exports = {
mode: ‘development‘,
devtool: ‘cheap-module-eval-source-map‘,
optimization: {
usedExports: true
}
}
// package.json 如果某些文件不需要做Tree Shaking,需要增加如下配置
"sideEffects": false, // 没有要处理的文件
"sideEffects": ["*.css"], // 任何css文件都不做Tree Shaking
Develoment 和 Production 模式的区分打包
webpack.common.js
const path = require(‘path‘);
const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);
const CleanWebpackPlugin = require(‘clean-webpack-plugin‘);
module.exports = {
entry: {
main: ‘./src/index.js‘
},
module: {
// 相关loader配置(此处省略)
rules: [ ... ]
},
plugins: [
new HtmlWebpackPlugin({
template: ‘src/index.html‘
}),
new CleanWebpackPlugin([‘dist‘], {
root: path.resolve(__dirname, ‘../‘)
})
],
output: {
filename: ‘[name].js‘,
path: path.resolve(__dirname, ‘../dist‘)
}
}
webpack.dev.js
const webpack = require(‘webpack‘);
const merge = require(‘webpack-merge‘);
const commonConfig = require(‘./webpack.common.js‘);
const devConfig = {
mode: ‘development‘,
devtool: ‘cheap-module-eval-source-map‘,
devServer: {
contentBase: ‘./dist‘,
open: true,
port: 8080,
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
optimization: {
usedExports: true
}
}
module.exports = merge(commonConfig, devConfig);
webpack.prod.js
const merge = require(‘webpack-merge‘);
const commonConfig = require(‘./webpack.common.js‘);
const prodConfig = {
mode: ‘production‘,
devtool: ‘cheap-module-source-map‘
}
module.exports = merge(commonConfig, prodConfig);
Webpack 和 Code Splitting
- 代码分割,和webpack无关
- webpack中实现代码分割,两种方式
- 同步代码: 只需要在webpack.common.js中做optimization的配置即可
- 异步代码(import): 异步代码,无需做任何配置,会自动进行代码分割,放置到新的文件中
同步加载
// index.js
import _ from ‘lodash‘
console.log(_.join([‘a‘, ‘b‘], ‘-‘))
// webpack.common.js
module.exports = {
optimization: {
splitChunks: {
chunks: ‘all‘
}
}
}
异步加载
注意需要借助babel插件来支持该语法
npm install --save-dev @babel/plugin-syntax-dynamic-import
// .babelrc
{
plugins: ["@babel/plugin-syntax-dynamic-import"]
}
// index.js
function getComponent() {
return import(/* webpackChunkName:"lodash" */ ‘lodash‘).then(({ default: _ }) => {
var element = document.createElement(‘div‘)
element.innerHTML = _.join([‘a‘, ‘b‘], ‘-‘)
return element
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
/* webpackChunkName:"lodash" */
webpack魔法注释的作用是对异步加载的lodash打包生成的文件进行重命名,即为vendors~lodash.js
,不设置的时候是0.js
SplitChunksPlugin详细配置参数
module.exports = {
//...
optimization: {
splitChunks: {
chunks: ‘async‘,
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: ‘~‘,
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
}