目前负责的项目,是未经过脚手架和其余框架搭建的 react 项目。开发过程当中,启动项目和热更新速度都不是很理想;打包构建时,速度也比较缓慢且因为单个文件过大,用户在访问时,加载动画的时间也比较长。因此打算对其进行部分优化工做。 本着提高 webpack 性能,最直接的方式就是升级 webpack 版本的思路。对项目中的进行了一系列的升级和优化。升级和优化的结果以下: 编译速度方面:javascript
体积方面:css
查看性能相关的插件:java
speed-measure-webpack-plugin
测量 plugin、loader 等时间;webpack-bundle-analyzer
打包分析工具。// 检查过期的依赖包
npm outdated
// 安装最新版本依赖包
npm install package@latest
复制代码
// 若是不存在默认的 webpack.config.js 配置,则须要 --config 指定配置文件
node --trace-deprecation node_modules/webpack/bin/webpack.js
复制代码
添加如下配置选项,检查构建是否正常运行(完成后删除这些配置选项)。node
module.exports = {
node: {
Buffer: false,
process: false
},
}
复制代码
npm install webpack@latest -D
复制代码
具体注意事项查看官方迁移指南:To v5 from v4react
asset
代替file-loader url-loader raw-loader
。terser-webpack-plugin
。cache: filesystem
持久缓存。可以大大提高二次构建速度(修改配置文件除外)。{
cache: {
type: "filesystem",
buildDependencies: {
// config 添加为 buildDependency,以便在改变 config 时得到缓存无效
config: [__filename],
},
name: process.env.NODE_ENV,
version: "1.0.0",
},
}
复制代码
thread-loader
进行多进程构建。// worker 启动有必定的消耗,
// 能够预热 worker 池
const jsWorkerPool = {
workerParallelJobs: 80,
poolTimeout: 2000,
};
const cssWorkerPool = {
workerParallelJobs: 10,
poolTimeout: 2000,
};
threadLoader.warmup(jsWorkerPool, ["babel-loader"]);
threadLoader.warmup(cssWorkerPool, ["css-loader", "less-loader"]);
复制代码
devServer: {
...
watchOptions: {
// 延迟构建
aggregateTimeout: 1500,
ignored: /node_modules/,
},
},
复制代码
style-loader
,能够实现模块热替换;[react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin)
插件;{
plugins: [
new ReactRefreshWebpackPlugin()
]
}
复制代码
// .babelrc
{
"plugins": [
...,
"react-hot-loader/babel"
]
}
// index.js
import { hot } from 'react-hot-loader';
...
const App = hot(module)(() => ...);
render(<App />, document.getElementById('root'));
复制代码
打包后体积优化,主要是使用 Gzip 压缩,将打包后体积较大的文件使用 Gzip 压缩。项目中的两个大文件体积分别减小了 77%和 86% 左右,大大加快了页面的加载速度。 webpack
Gzip(GNU- ZIP) 是一种压缩技术。通过压缩的页面能大大加快浏览器端的加载速度。 启用 Gzip 须要服务器端和浏览器端都支持:服务器端压缩(提供压缩的文件),浏览器端解压。 注意:git
其余体积优化须要修改业务相关代码较多,就暂未进行优化。github
DeprecationWarning:[DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK] DeprecationWarning: Compilation.hooks.normalModuleLoader was moved to NormalModule.getCompilationHooks(compilation).loader
speed-measure-webpack-plugin
插件兼容性问题,目前尚未彻底和 webpack5 兼容,能够在优化完成后移除相关配置。web
Error: Cannot find module 'webpack-cli/bin/config-yargs
npm
4.X版本的 webpack-cli 移除了yargs包,须要使用 webpack serve
启动webpack-dev-server
。
// package.json
{
"script": {
"dev": "webpack serve --config webpack.dev.js"
}
}
复制代码
Support for the experimental syntax 'classProperties' isn't currently enabled
@babel/preset-env
不包含小于 Stage 3 的语法提案,须要手动安装相应插件。须要安装插件@babel/plugin-proposal-class-properties
。
//.babelrc
{
"plugin":[
"@babel/plugin-proposal-class-properties"
]
}
复制代码
Support for the experimental syntax 'decorators-legacy' isn't currently enabled
缘由同上,须要安装插件@babel/plugin-proposal-decorators
。
//.babelrc
{
"plugin":[
["@babel/plugin-proposal-decorators", {"legacy": true}]
]
}
复制代码
expose-loader
升级后,报错:ValidationError: Invalid options object. Expose Loader has been initialized using an options object that does not match the API schema.
// webpack 配置文件
module: {
rules:[
...,
{
use: {
loader: "expose-loader",
options: {
exposes: "videojs"
}
}
}
]
}
// **.js 使用
require('videojs');
复制代码
webpack.HotModuleReplacementPlugin
和hot: true
共同使用时,没法热更新。
hot: true
会自动添加webpack.HotModuleReplacementPlugin
插件,无需再次添加配置。 7. speed-measure-webpack-plugin
插件在 build 时,没法使用。 8. webpack5 再也不为 Node.js 提供自动引入polyfills。
根据错误提示修改便可。
生产环境中构建完成,可是未退出命令
thread-loader
插件在生产环境中,预热 worker 池会致使此问题。
升级后,webpack 对代码要求更加严格,须要按需修改。