Create react App eject后 webpack 的优化配置
Create react App 是一个官方支持的创建 react 单页应用程序的方法。它提供了一个零配置的现代构建设置。虽然开箱即用,但是开发中我们还是少不了做一些修改,下面总结了一些常用的配置,本文基于webpack4.44.2进行配置
关于eject
执行npm run eject命令会将react-scripts释放到本地项目中,可以通过修改对应的文件完成配置。同时会删除react-scripts依赖包,修改package.json中命令。命令执行完毕以后,我们就会看到本地项目中多出了scripts和config两个目录文件。同时,package.json文件命令也被修改了。
此时,如果在执行启动或者打包命令,就是直接执行的scripts目录下对应的文件了。我们可以很方便的根据需要修改对应的文件配置即可。
但值得注意的是,npm run eject命令是不可逆的,即执行之后不可恢复,这就造成了如果后续我们想通过脚手架的react-scripts包增加新的特性,比如PWA支持,是不可行的
关闭生产环境 sourcemap
通常在开发的时候,我们会配置开发环境生成 sourcemap 文件,方便调试,但是在生产环境都要关闭,避免代码泄露和打包多余文件,体积太大。
可以在项目根目录创建'.env'文件,配置如下内容:
//.envGENERATE_SOURCEMAP=false
noParse
如果一些第三方模块没有AMD/CommonJS规范版本,可以使用 noParse 来标识这个模块,这样 webpack 会引入这些模块,但是不进行转化和解析,从而提升 webpack 的构建速度,例如:jquery 、lodash (被忽略的库不能有import、require、define的引入方式),noParse 属性的值是一个正则表达式或者是一个 function
//webpack.config.jsmodule.exports = {
//...
module: {
noParse: /jquery|lodash/
}
}
splitChunks抽取公共代码
splitChunks可以抽取公共代码,拆分业务代码和第三方代码库,防止打包文件过大,代码示例如下:
//webpack.config.jsoptimization: {
//...
splitChunks: {
chunks: 'all',
minSize: 30000, //字节 引入的文件大于30kb才进行分割
minChunks: 1, //模块至少使用次数
automaticNameDelimiter: '~', //缓存组和生成文件名称之间的连接符
name: true,
cacheGroups: {
vender: {
name: 'vendor',
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: 20
},
react: {
name: 'react',
test: (module) => /react|redux/.test(module.context),
chunks: 'initial',
priority: 11
},
lodash: {
name: 'lodash',
test: (module) => /lodash/.test(module.context),
chunks: 'initial',
priority: 15
},
antdm: {
name: 'antd-mobile',
test: (module) => /antd-mobile/.test(module.context),
chunks: 'initial',
priority: 12
}
}
}
}
thread-loader
webpack4 官方提供了一个thread loader,把这个 loader 放置在其他 loader 之前, 放置在这个 loader 之后的 loader 就会在一个单独的 worker池里运行,一个worker 就是一个nodeJS 进程,每个单独进程处理时间上限为600ms,各个进程的数据交换也会限制在这个时间内。
**注意:如果项目小,文件不多,无需开启多进程打包,打开反而会变慢,因为开启进程是需要花费时间的
- 安装依赖:
cnpm install thread-loader -D
- webpack配置:
module.exports = { module: {
rules: [
{
test: /\.js$/,
include: path.resolve("src"),
use: [
"thread-loader",
// your loader (e.g babel-loader)
]
}
]
}
}
HardSourceWebpackPlugin(用于开发环境,可以取代DllPlugin)
HardSourceWebpackPlugin 为模块提供中间缓存,缓存默认的存放路径是: node_modules/.cache/hard-source。
配置 hard-source-webpack-plugin,首次构建时间没有太大变化,但是第二次开始,构建时间大约可以节约 80%。由于生产环境的打包次数有限,所以此插件主要用于开发环境,提升打包速度。与DllPlugin相比配置更加简单,效率也更高。
- 安装依赖:
cnpm install hard-source-webpack-plugin -D
- webpack 的配置:
//webpack.config.jsvar HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
//...
plugins: [
//用于开发环境
isEnvDevelopment &&
new HardSourceWebpackPlugin()
]
}
HardSourceWebpackPlugin文档
列出了一些你可能会遇到的问题以及如何解决,例如热更新失效,或者某些配置不生效等。
webpack-bundle-analyzer
借助 webpack-bundle-analyzer 可以查看哪些包的体积较大,
- 安装依赖:
cnpm install webpack-bundle-analyzer -D
- 配置如下:
//webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
//....
plugins: [
//...
new BundleAnalyzerPlugin(),
]
}
npm run build 构建,会默认打开: http://127.0.0.1:8888/,可以看到各个包的体积,进一步使用 splitChunks 进行拆分,打包后对比,优化完成后,上线前最好删除此插件和配置
webpack自身的优化(已经默认开启,无需配置)
- tree-shaking
如果使用ES6的import 语法,那么在生产环境下(mode:production),会自动移除没有使用到的代码。
- scope hosting 作用域提升
变量提升,可以减少一些变量声明。在生产环境下,默认开启。
- 缩小文件匹配范围(include/exclude)
- 缓存loader的执行结果(cacheDirectory)
- IgnorePlugin:webpack 的内置插件,作用是忽略第三方包指定目录
例如: moment (2.24.0版本) 会将所有本地化内容和核心功能一起打包,我们就可以使用 IgnorePlugin 在打包时忽略本地化内容。
在使用的时候,如果我们需要指定语言,那么需要我们手动的去引入语言包,例如,引入中文语言包:
import moment from 'moment';
import 'moment/locale/zh-cn';// 手动引入
- 多进程压缩的优化:Webpack 默认使用的是 TerserWebpackPlugin,默认开启了多进程和缓存,构建时,你的项目中可以看到 terser 的缓存文件 node_modules/.cache/terser-webpack-plugin,没必要单独安装以下插件,webpack-parallel-uglify-plugin,uglifyjs-webpack-plugin 配置 parallel.
以上是 Create react App eject后 webpack 的优化配置 的全部内容, 来源链接: utcz.com/z/382259.html