vue-cli/webpack4.x 打包--webpack配置--chainWebpack
webpack-chain是啥
针对Webpack
的流式配置方案
webpack-chain优势
- 动态修改配置信息
- 链式调用,避免深层的嵌套配置
- 跨项目共享 webpack 配置对象
webpack-chain 中的核心 API 接口之一是 ChainedMap, 返回对象也都是 ChainMap,这样可以实现链式调用,简化操作
// 清空当前 Map 的所有属性 clear() // 通过键值从 Map 移除单个配置. delete(key) // Map中是否存在一个配置值的特定键,返回真或假 has(key) // 返回 Map中已存储的所有值的数组 values() // 提供一个对象,这个对象的属性和值将映射进 Map。第二个参数为一个数组,表示忽略哪些属性 merge(obj, omit) // handler: ChainedMap => ChainedMap // 一个把ChainedMap实例作为单个参数的函数 batch(handler) // condition: Boolean // whenTruthy: ChainMap -> any, 条件为真时执行 // whenFalsy: ChainSet -> any, 条件为假时执行 when(condition, whenTruthy, whenFalsy) // 获取 Map 中相应键的值 get(key) // 先调用 get,如果找不到对应的值, 就返回 fn 函数返回的结果 getOrCompute(key, fn) // 配置键值对 set(key, value)
对于ChainSet
和ChainMap
对象都有条件配置方法when
,可以在某些很多场景下取代 if-else,保持配置的链式调用,让代码更加优雅。
举例
config.when(
process.env.NODE === 'production',
config.plugin('size').use(SizeLimitPlugin)
)
配置路径别名
config.resolve.alias
.set(key, value)
.set(key, value)
.delete(key)
.clear()
举例:
config.resolve.alias
.set('assets',resolve('src/assets'))
.set('components',resolve('src/components'))
.set('static',resolve('src/static'))
.delete('static') // 删掉指定的别名
plugins
添加一个插件
// 先指定名字(这个名字是自定义的),然后通过 use 添加插件
config
.plugin(name)
.use(WebpackPlugin, args)
举例:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// 先指定名字(这个名字可以自定义),然后通过 use 添加插件,use 的第二个参数为插件参数,必须是一个数组,也可以不传
config.plugin('extract')
.use(ExtractTextPlugin, [{
filename: 'build.min.css',
allChunks: true,
}])
移除插件
config.plugins.delete('extract') //extract:指定的插件名
指定插件在 xx 插件之前/之后调用
在extract 插件之前执行
const htmlWebpackPlugin = require('html-webpack-plugin');
config.plugin('html')
.use(htmlWebpackPlugin)
.before('extract')
在 extract 插件之后执行,调用 after 方法
config.plugin('html')
.use(htmlWebpackPlugin)
.after('extract')
动态修改插件参数
// 使用 tap 方法修改参数
config
.plugin(name)
.tap(args => newArgs)
举例
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
修改插件初始化过程
自定义插件的实例化的过程
// 通过 init 方法,返回一个实例,这将代替原有的实例化过程
config
.plugin(name)
.init((Plugin, args) => new Plugin(...args));
loader
添加一个 loader
config.module
.rule(name)
.use(name)
.loader(loader)
.options(options)
举个例子:
config.module
.rule('ts')
.test(/\.tsx?/)
.use('ts-loader')
.loader('ts-loader')
.options({
transpileOnly: true
})
.end()
修改 loader 参数
可通过 tap 方法修改 loader 的参数:
config.module
.rule('ts')
.test(/\.tsx?/)
.use('ts-loader')
.loader('ts-loader')
.tap(option => {
// 一系列
return options;
})
.end()
移除一个 loader
// 通过 uses 对象的 delete 方法,根据 loader 的 name 删除
config.module
.rule('ts')
.test(/\.tsx?/)
.uses.delete('ts-loader')
在所有的配置完成之后,可以通过调用config.toConfig()
来拿到最后的配置对象,可以直接作为webpack
的配置。
optimization
Webpack 中的optimization
也是一个比较庞大的对象,参照官方文档:https://webpack.js.org/configuration/optimization/。
splitChunks
和 minimizer
为例来配置一下:
config.optimization.splitChunks({
chunks: "async",
minChunks: 1, // 最小 chunk ,默认1
maxAsyncRequests: 5, // 最大异步请求数, 默认5
maxInitialRequests : 3, // 最大初始化请求数,默认3
cacheGroups:{ // 这里开始设置缓存的 chunks
priority: 0, // 缓存组优先级
vendor: { // key 为entry中定义的 入口名称
chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是async)
test: /react|vue/, // 正则规则验证,如果符合就提取 chunk
name: "vendor", // 要缓存的 分隔出来的 chunk 名称
minSize: 30000,
minChunks: 1,
}
}
});
// 添加一个 minimizer
config.optimization
.minimizer('css')
.use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: {} }])
// 移除 minimizer
config.optimization.minimizers.delete('css')
// 修改 minimizer 插件参数
config.optimization
.minimizer('css')
.tap(args => [...args, { cssProcessorOptions: { safe: false } }])
来源:https://zhuanlan.zhihu.com/p/364092415