webpack高级使用
# 抽离公共代码和第三方代码
optimization: {
...
// 分割代码块
splitChunks: {
chunks: 'all',
/**
* initial 入口chunk,对于异步导入的文件不处理
async 异步chunk,只对异步导入的文件处理
all 全部chunk
*/
// 缓存分组
cacheGroups: {
// 第三方模块
vendor: {
name: 'vendor', // chunk 名称
priority: 1, // 权限更高,优先抽离,重要!!!
test: /node_modules/,
minSize: 0, // 大小限制
minChunks: 1 // 最少复用过几次
},
// 公共的模块
common: {
name: 'common', // chunk 名称
priority: 0, // 优先级
minSize: 0, // 公共模块的大小限制
minChunks: 2 // 公共模块最少复用过几次
}
}
}
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 动态数据-懒加载
import('**').then(res => {
res.default.** // 注意default
})
1
2
3
2
3
# module chunk bundle 的区别
- module- 各个源码文件,webpack 中一切皆模块
- chunk - 多模块合并成的,如 entry import splitChunk
- bundle- 最终的输出文件
# webpack 性能优化 - 构建速度
# 优化 babel-loader
{
test:八.js$/,
use: ["babel-loader?cacheDirectory'],//开启缓存
include: path. reso lve(dirname,'src"),//明确范围
//// 排除范围,include 和 exclude 两者选一个即可
// exclude: path. resolve(_dirname,'node_ modules")
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# IgnorePlugin 避免引入无用模块
import moment from 'moment'
- 默认会引入所有语言 JS代码,代码过大
- 如何只引入中文?
// webpack.prod.js
//忽略 moment 下的 / Locale 目录
new webpack.Ignoreplugin(/\.\/locale/, /moment/
1
2
3
4
2
3
4
# noParse 避免重复打包
# happyPack 多进程打包
- JS单线程,开启多进程打包
- 提高构建速度(特别是多核 CPU)
// module.rules
// js
{
test: /\.js$/,
// 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
use: ['happypack/loader?id=babel'],
include: srcPath,
// exclude: /node_modules/
},
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
// plugins
// happyPack 开启多进程打包
new HappyPack({
// 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
id: 'babel',
// 如何处理 .js 文件,用法和 Loader 配置中一样
loaders: ['babel-loader?cacheDirectory']
}),
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# ParallelUglifyPlugin 多进程压缩JS
- webpack 内置 Uglify 工具压缩 JS
- JS单线程,开启多进程压缩更快
- 和 happyPack 同理
// plugins
// 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
new ParallelUglifyPlugin({
// 传递给 UglifyJS 的参数
// (还是使用 UglifyJS 压缩,只不过帮助开启了多进程)
uglifyJS: {
output: {
beautify: false, // 最紧凑的输出
comments: false, // 删除所有的注释
},
compress: {
// 删除所有的 `console` 语句,可以兼容ie浏览器
drop_console: true,
// 内嵌定义了但是只用到一次的变量
collapse_vars: true,
// 提取出出现多次但是没有定义成变量去引用的静态值
reduce_vars: true,
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
开发环境下
# 自动刷新 热更新
热更新需要开启监听范围
// 增加,开启热更新之后的代码逻辑
if (module.hot) {
module.hot.accept(['./math'], () => {
const sumRes = sum(10, 30)
console.log('sumRes in hot', sumRes)
})
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# DllPlugin 动态链接库插件
前端框架如 vue React,体积大,构建慢
较稳定,不常升级版本
同一个版本只构建一次即可,不用每次都重新构建
webpack 已内置 DllPlugin 支持
DlPlugin -打包出dll文件
react.dll.js
manifest.json // 索引文件
DlIlReferencePlugin - 使用 dlll文件
index.html 中引入react.dll.js文件
然后配置索引地址
plugins
new DllPlugin({
// 动态链接库的全局变量名称,需要和 output.library 中保持一致
// 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
// 例如 react.manifest.json 中就有 "name": "_dll_react"
name: '_dll_[name]',
// 描述动态链接库的 manifest.json 文件输出时的文件名称
path: path.join(distPath, '[name].manifest.json'),
}),
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
使用: 创建webpack.dll.js
const path = require('path')
const DllPlugin = require('webpack/lib/DllPlugin')
const { srcPath, distPath } = require('./paths')
module.exports = {
mode: 'development',
// JS 执行入口文件
entry: {
// 把 React 相关模块的放到一个单独的动态链接库
react: ['react', 'react-dom']
},
output: {
// 输出的动态链接库的文件名称,[name] 代表当前动态链接库的名称,
// 也就是 entry 中配置的 react 和 polyfill
filename: '[name].dll.js',
// 输出的文件都放到 dist 目录下
path: distPath,
// 存放动态链接库的全局变量名称,例如对应 react 来说就是 _dll_react
// 之所以在前面加上 _dll_ 是为了防止全局变量冲突
library: '_dll_[name]',
},
plugins: [
// 接入 DllPlugin
new DllPlugin({
// 动态链接库的全局变量名称,需要和 output.library 中保持一致
// 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
// 例如 react.manifest.json 中就有 "name": "_dll_react"
name: '_dll_[name]',
// 描述动态链接库的 manifest.json 文件输出时的文件名称
path: path.join(distPath, '[name].manifest.json'),
}),
],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# webpack 性能优化 - 产出代码
体积更小
合理分包,不重复加载
速度更快、内存使用更少
小图片 base64 编码
bundle 加 hash
懒加载
提取公共代码
IngorePlugin
使用cdn 加速
- publicPath
使用 production
- 更改mode配置 , production会自动压缩代码
- Vue React 等会自动删掉调试代码(如开发环境的 warning)
- 启动 Tree-Shaking
Scope Hosting
- 代码体积更小
- 创建函数作用域更少
- 代码可读性更好
# ES6 Module 和 Commonjs 区别
两个都是模块化解决方案
- ES6 Module 静态引入,编译时引入
- Commonjs 动态引入,执行时引入
- 只有 ES6 Module 才能静态分析,实现 Tree-Shaking
上次更新: 2023/09/17, 16:36:29