webpack 5.0新特性
借鉴网上的图,大致窥探一下webpack5.0的一些新特性。
包依赖分析
在拆包之前,我们通常都会使用一些插件去分析我们的包模块的依赖,webpack-bundle-analyzer
就是一款不错的插件,通过webpack-bundle-analyzer
我们可以合理分析依赖情况
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-cheap-module-source-map',
entry: ['./src/index.tsx'],
plugins: [
new Webpack.HotModuleReplacementPlugin(),
new BundleAnalyzerPlugin(),
],
});
Webpack 代码拆分
我们可以使用splitChunks 进行精细控制代码分割,也就是俗称的拆包。
使用splitChunks
我们可以提取公共代码,防止代码被重复打包,拆分过大的js文件,合并零散的js文件等:
splitChunks拆包
1、使用splitChunks 提取共有代码,拆分业务代码与第三方库
optimization: {
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,// 分割出去的代码最小体积 0为不限制
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$|.less$/,
chunks: 'all',// 将所有的重复模块抽离出来
enforce: true,
},
vendor: {
name: 'vendor',
test: (module) =>
/(react|react-dom|react-router-dom/.test(
module.context,
),
chunks: 'initial',// 引入组件的方式:同步加载,异步加载:'async'
priority: 11,
},
libs: {
name: 'libs',
test: (module) => /(moment|antd|lodash)/.test(module.context),
chunks: 'all',
priority: 14,
},
common: {
chunks: 'async',
test: /[\\/] node_modules[\\ / ] /,
name: 'common',
minChunks: 3,// 被几个代码块引用才会分割
maxAsyncRequests: 5,
maxSize: 1000000,
priority: 10,
},
},
},
},
动态加载
import('./math').then(math => {
console.log(math.add(1,2))
})
const math = lazy(() => import('./math'))
拆分tailwindcss
未移除之前,vendors.js有22mb大小:
tailwind.config.js 中配置移除项:
// tailwind.config.js
purge: {
// Learn more on https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css
enabled: true,
content: [
'./src/components/**/*.tsx',
'./src/context/**/*.tsx',
'./src/layouts/**/*.tsx',
'./src/pages/**/*.tsx',
],
},
移除之后,bundle文件体积大小如下:
Tree shaking移除未使用的js代码
production模式实际上是由TerserPlugin来处理的,默认开启压缩也是基于此插件处理。tree-shaking 需要基于es6模块化语法。我们可以直接通过手动的方式告诉webpack, 哪些东西是不需要处理的,可以通过package.json去配置副作用:
{
"sideEffects": [
"*.css" // 指定不需要shaking处理的文件
]
}
为什么需要基于es6 模块语法呢?
因为ES Module
在js编译阶段就可以确定模块之间的依赖关系(import),并不需要执行就可以确认模块的导入、导出。所以我们并不需要代码执行就可以根据ESM确定模块之间的规则从而实现Tree Shaking
,我们称之为静态分析特性。
Webpack 资源持久化缓存
每个打包的资源文件有唯一的hash值,即“文件指纹”。修改后只有受影响的文件hash变化,就可以做到“增量式更新”。可以避免部署过程中,存在更新的时间间隔。也不会出现用户浏览器某些使用到的文件是旧的缓存文件,某些使用的是新的文件。
{
plugins: [
new MiniCssExtractPlugin({
filename: '[name]_[contenthash:8].css',// contenthash 根据css内容去计算hash值
chunkFilename: '[name].[contenthash].css',
}),
],
output: {
filename: '[name].[hash].bundle.js',
chunkFilename: '[name].[chunkhash:8].bundle.js'
}
}
使用contenthash,这样每个资源文件都会有自己的独立的hash值。这样我们对局部的修改只会影响到局部文件,而不需要进行整体的变更和部署