推荐阅读
前言
前面介绍了打包react项目一些常规的配置,接下来两章内容都会从打包优化方方面着手,介绍在打包的过程中如何提升打包速度,从而引入不同环境(development
,production
)下是否需要这些优化。
正文
优化不能盲目的进行,想要考虑从那几个方面着手,下面是我总结几个方面
- Node,Npm,Yarn的更新
- 合理使用resolve
- 在较少的模块下使用loader
- 保证plugins的可靠性
说明一下:
- 在打包项目的时候使用的是yarn 或者 npm 每一次包管理器的迭代都会更新内部的一些依赖,其底层需要依赖node.js 环境。所以Node,Npm,Yarn的更新对打包速度是有影响的。
- resolve的mainFiles,alias, extensions 字段都是为了在编码的过程中检索代码重复编写,其内部进行了文件的查找。但是如果使用太多会导致在打包的过程中不断的查找文件,降低速度。
- loader 是解释代码,对于js 或者 jsx 文件我们没有必要对 node_moudles 下的这类文件进行再次编译
- 对于项目的打包优化,其主要是使用插件进行优化,能够合理的使用可靠性比较高的插件对于提升速度是必不可少的。
综上所述可以看到优化的主力军就是plugins,所以我将会介绍几种插件的使用。
clean-webpack-plugin
先看一下 output
的一个配置
output: {
filename: '[name].[hash:8].js',
path: path.resolve(process.cwd(), 'dist'),
},
# 每次打包就会在打包文件名后跟一个 8 位的 hash 值,所以每次打包生产的文件名都不一样,这样就会导致 dist 文件夹下有非常多的上次打包文件。
为了解决上述文件可以使用 clean-webpack-plugin
插件,他的作用就是每次打包就会清理指定的文件夹。
- 安装
npm install --save-dev clean-webpack-plugin
- 使用
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports={
# ...
output: {
filename: '[name].[hash:8].js',
path: path.resolve(process.cwd(), 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
}),
# 会清空 output 配置的 path 目录
new CleanWebpackPlugin(),
],
}
第三方模块打包
先看一段配置
optimization: {
runtimeChunk: {
name: 'runtime'
},
usedExports: true,
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'vendors'
}
}
}
},
# 这段配置的意思是把第三方模块都打包到一个指定的文件。如果没有配置这个选项,会把所有的打包项输入到 output 的 filename 文件里面.
但是上面的配置纯在一个缺陷,每次打包都会对第三方进行打包。对于实际开发中,对于类似于react
,react-dom
等模块,只需要打包一次就可以,每次打包的引入只需要引入第一次打包的第三方模块即可。
我们可以增加一个webpack.dll.js
配置文件
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack')
module.exports = {
mode: 'production',
entry: {
vendors: ['react', 'react-dom', 'loadsh']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, '../dll'),
library: '[name]'
},
plugins: [
new webpack.DllPlugin({
name: '[name]',
path: path.resolve(__dirname, '../dll/[name].manifest.json'),
})
]
}
# 会将 react react-dom lodash 打包输入至 dll 目录下 vendors.dll.js, 使用 webpack.DllPlugin 这个插件会生成一个名为 manifest.json 的文件,这个文件是用来让 DLLReferencePlugin 映射到相关的依赖上去的,
此时在执行打包的过程中,会发现我们打包的 vendors.dll.js
并不会引入到打包生成的index.js 文件里面,所以我们要用到另外一个插件add-asset-html-webpack-plugin
在 webpack.config.js
中添加如下配置
plugins:[
new AddAssetHtmlPlugin({
filepath: path.resolve(__dirname, '../dll/vendors.dll.js'),
}),
]
这样就引入了打包后的vendors.dll.js
。查看wenpack 官方文档就会发现 webpack.DllPlugin
和DllReferencePlugin
是要同时使用。
在 webpack.config.js
中添加如下配置
plugins:[
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, '../dll/vendors.manifest.json'),
})
]
在package.json
中添加如下脚本
"build:dll": "webpack --config ./config/webpack.dll.js"
# --config 后面填写配置文件路径
执行 npm run build:dll
或者 yarn build
就会把react
,react-dom
,loadsh
模块单独打包。
这样我们只需要执行一遍 build ,再次执行 build 的时候,就会在vendors.manifest.json文件里面找是否已经打包过,如果打包过就不在进行打包,使用上一次,如果没有就去nodo_modules里面查找依赖打包。
结束
本文到这里已经结束了,当然打包优化是一个不断探索和研究的过程,远不止我写的这么点,还有 按需引入,多进程打包,合理使用 sourceMap,本机配置等多个方面因素的影响。也就不去写了,下一节我们将探讨不同环境下的不同配置。