三、Webpack优化配置
性能优化
性能优化包含开发环境优化和生产环境优化。
- 开发环境
- 优化打包构建速度
- 优化代码调试
- 生产环境
- 优化打包构建速度
- 优化代码运行的性能
开发环境
HMR
即热更新:一个模块发生变化,只会重新打包这一个模块。
在devServer
中开启
1 | { |
样式文件
样式文件可以使用热更新,因为
style-loader
内部实现了js文件
默认不使用HMR功能,需要手动修改支持HMR。且只能处理非入口文件。
1
2
3
4
5
6
7
8if (module.hot) {
// 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
module.hot.accept('./print.js', function() {
// 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
// 会执行后面的回调函数
print();
});
}HTML文件
默认不支持,需要修改webpack中entry入口
1
2
3module.exports = {
entry: ['./src/js/index.js', './src/index.html']
}
source-map
source-map是一种提供源代码到构建后代码映射技术。开启source-map只需要在devServer中开启devtool
即可。
1 | devServer: { |
关于devtool
的选项
选项 | 位置 | 特点 | 错误原因及位置 |
---|---|---|---|
source-map | 外部 | 错误代码准确信息 源代码的错误位置 | |
inline-source-map | 内联 | 只生成一个内联source-map | 错误代码准确信息 源代码的错误位置 |
hidden-source-map | 外部 | 错误代码错误原因,但是没有错误位置 | 不能追踪源代码错误,只能提示到构建后代码的错误位置 |
eval-source-map | 内联 | 每一个文件都生成对应的source-map,都在eval | 错误代码准确信息 源代码的错误位置 |
nosources-source-map | 外部 | 错误代码准确信息, 但是没有任何源代码信息 | |
cheap-source-map | 外部 | 只能精确的行 | 错误代码准确信息 源代码的错误位置 |
cheap-module-source-map | 外部 | module会将loader的source map加入 | 错误代码准确信息 源代码的错误位置 |
内联和外部的区别:外部生成了文件,内联没有;内联速度比外部快
开发环境与生产环境下source-map的选择:
开发环境:速度快,调试更友好
- 速度快
eval-cheap-souce-map
eval-source-map
- 调试友好
souce-map
cheap-module-souce-map
cheap-souce-map
因此开发环境下可以选择:
eval-source-map
或者eval-cheap-module-souce-map
- 速度快
生产环境
不隐藏源代码(便于调试)
source-map
cheap-module-souce-map
因此源代码
nosources-source-map
全部隐藏
hidden-source-map
只隐藏源代码,会提示构建后代码错误信息
oneOf
1 | module: { |
只需要将loader放入到oneOf
数组中即可,使用oneOf
后不能有两个loader处理同一类型的文件,因此需要将相同的loader提取到外边
缓存
babel缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3 },
targets: {
chrome: '60',
firefox: '50'
}
}
]
],
// 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true
}
}文件资源缓存
hash
和整个项⽬目的构建相关,只要项⽬目⽂文件有修改,整个项⽬目构建的 hash 值就会更更改
chunkhash
和 webpack 打包的 chunk 有关,不不同的 entry 会⽣生成不不同的 chunkhash 值
contenthash
根据⽂文件内容来定义 hash ,⽂文件内容不不变,则 contenthash 不不变
一般情况下js文件使用
chunkhash
,css文件和图片使用contenthash
,图片文件使用hash
生产环境
去除无用代码
可以按需加载需要使用的代码,减少代码体积。
- 使用ES6模块化
- 开启
production
环境
此方法可能会将css资源忽略掉,因此可以在package.json中进行配置。
1 | "sideEffects": [ |
代码分割
即按需加载,生成多个js文件。
根据入口文件进行分割
1
2
3
4
5
6
7
8
9module.exports = {
// 单入口
// entry: './src/js/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个bundle
index: './src/js/index.js',
test: './src/js/test.js'
}
}分割node_moudle模块
1
2
3
4
5
6
7
8
9
10
11module.exports = {
/*
1. 可以将node_modules中代码单独打包一个chunk最终输出
2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
*/
optimization: {
splitChunks: {
chunks: 'all'
}
}
}通过JS代码使某个文件被单独打包
此时webpack的入口可以设置单入口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14/*
通过js代码,让某个文件被单独打包成一个chunk
import动态导入语法:能将某个文件单独打包
*/
import(/* webpackChunkName: 'test' */'./test')
.then(({ mul, count }) => {
// 文件加载成功~
// eslint-disable-next-line
console.log(mul(2, 5));
})
.catch(() => {
// eslint-disable-next-line
console.log('文件加载失败~');
});
懒加载和预加载
只需要在触发某个条件时才引入外部文件。
1 | document.getElementById('btn').onclick = function() { |
PWA
渐进式网络开发应用程序(离线可访问)
在webpack中使用pwa需要安装插件workbox-webpack-plugin
1 | yarn add workbox-webpack-plugin -D |
修改webpack配置
1 | plugins: [ |
在入口文件配置serviceworker
1 | // code |
如果发生eslint错误,则可以在package.json中进行修改。
1
2
3
4
5
6
7
8 {
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
}
}
多进程打包
安装插件
1 | yarn add thread-loader -D |
一般多进程对babel-loader进行。只需要将thread-loader
放在其他loader前即可。
1 | { |
多进程不一定会使打包时间变短,需合理使用。因为进程启动也需要消耗时间。
使用CDN
在webpack中配置字段externals
即可。
1 | externals: { |
忽略后需在html手动引入CDN链接。
dll
安装插件
1 | yarn add add-asset-html-webpack-plugin -D |
在webpack.config.js
同目录建立一个webpack-dll.js
文件。写入如下内容:
1 | /** |
在webpack.config.js
中使用
1 | const webpack = require('webpack') |