代码分离
就是将打包的js分离成多个js,按需加载,加载速度快,提高代码的加载性能。
Webpack中常用的代码分离:
入口起点:使用entry配置手动分离代码
防止重复:使用Entry Dependencies或者SplitChunksPlugin去重和分离代码
动态导入:通过模块的内联函数调用来分离代码
入口起点 即多入口 实现代码分离
首先将不相关的代码分离到不同文件,如 main.js、index.js
在 webpack.config.js 中配置多入口:
entry: {
main: './src/main.js',
index: './src/index.js'
},
output: {
filename: '[name].bundle.js', // 这里的 name 对应 entry 配置的 key
path: resolveApp('./build')
},缺点很明显:要配置非常多的入口
Entry Dependencies(入口依赖),用的不多
比如,index.js 和 main.js 都引入了一个相同的库,如 lodash,如果用上面的打包,打包后,两个js都会有这个库的代码,重复了
去重方法:
entry: {
main: {import: './src/main.js', dependOn: 'lodash'},
index: {import: './src/index.js', dependOn: 'lodash'},
lodash: 'lodash'
},
output: {
filename: '[name].bundle.js', // 这里的 name 对应 entry 配置的 key
path: resolveApp('./build')
},
// 如果有多个,写法可以是:
entry: {
main: {import: './src/main.js', dependOn: ['lodash', 'dayjs']},
index: {import: './src/index.js', dependOn: ['lodash', 'dayjs']},
lodash: 'lodash',
dayjs: 'dayjs'
},
// 或者
entry: {
main: {import: './src/main.js', dependOn: 'shared'},
index: {import: './src/index.js', dependOn: 'shared'},
shared: ['lodash', 'dayjs']
},SplitChunks,最常用的分离方式
解释:
它主要用 SplitChunksPlugin 插件来实现的,该插件在安装webpack时,已默认安装和集成,不需要单独安装和单独使用
只需要提供 SplitChunksPlugin 相关配置信息即可
SplitChunksPlugin 用法:
// index.js
// 同步加载
import dayjs from 'dayjs'
// 异步加载 lodash
import('lodash').then(res => {
})
// webpack.config.js
entry: {
main: './src/main.js',
index: './src/index.js',
},
output: {
filename: '[name].bundle.js', // 这里的 name 对应 entry 配置的 key
path: resolveApp('./build')
},
// 优化
optimization: {
// 对代码进行压缩相关设置
minimizer: [
// 去除打包时产生的txt说明文件
new TerserPlugin({
extractComments: false
})
],
// SplitChunksPlugin 代码分离
splitChunks: {
// async:chunks 的默认值,异步,表示只有代码异步加载库时,才会进行分离
// initial: 同步
// all:异步同步加载的库或文件,都进行分离,用法常用
chunks: 'all'
}
},optimization.splitChunks 其他几个常用的值:
minSize
默认20000,即20kb,拆分出来的包的最小限制,即拆分出来的包如果小于这个值,就不进行拆分
optimization: {
splitChunks: {
chunks: 'all',
minSize: 200000
}
},maxSize
将大于maxSize的包继续拆分,拆分成不小于minSize的包
optimization: {
splitChunks: {
chunks: 'all',
minSize: 200000,
maxSize: 1000000
}
},minChunks
表示导入的包至少被导入了几次,才会被拆分
optimization: {
splitChunks: {
chunks: 'all',
minSize: 200000,
maxSize: 1000000,
minChunks: 1
}
},cacheGroups
表示将匹配到的文件,如来自node_modules,都分离成指定的文件名
optimization: {
splitChunks: {
chunks: 'all',
minSize: 200000,
maxSize: 1000000,
minChunks: 1,
cacheGroups: {
// vendors 随便取的名字
vendors: {
test: /[\\/]node_modules[\\/]/,
filename: '[id]_vendors.js',
priority: -10 // 优先级最高
},
// 打包自己的有规则的文件,如 bar_01.js、bar_02.js,将它们都打包成 bar 开头的文件:
bar: {
test: /bar_/,
filename: '[id]_bar.js',
priority: -20
},
// 对引入多次的文件,也打包成特殊命名的文件
default: {
minChunks: 2,
filename: 'common_[id].js',
priority: -30 // 优先级最低
}
}
}
},optimization.chunkIds 配置
optimization.chunkIds配置告知webpack,打包生成的模块的id采用什么算法
optimization: {
// natural:自然数,一般不用
// named: 命名,会将引入的 文件路径+文件名+后缀+output.filename配置 拼接在一起
// deterministic:根据内部算法生成的ID,而且针对相同文件,id不变,默认值
chunkIds: 'deterministic'
},output.chunkFilename
用于引入文件打包命名,区分默认文件打包命名
output: {
filename: '[name].bundle.js'
chunkFilename: '[name].chunk.js'
}注:这里的 [name] 就是 optimization.chunkIds 设置的id,如果相对这个 name 进行自定义,可以在引入文件时,借助魔法注释(magic comments),如:
import(/* webpackChunkName: 'foo' */'./foo').then(res => {
})使用了魔法注释,加上 output.chunkFilename,最终打包的文件名:foo.chunk.js
在router.vuejs.org,搜索懒加载,就能看到路由的推荐写法,就是使用的魔法注释
