vue-cli文档
1.webpack-chain
1.定义
- 通过链式调用操作webpack 配置对象。(chain:链子) 直接修改配置对象
- chainWebpack 通过链式编程的形式,来修改默认的 webpack 配置
2.包含的对象ChainedMap和ChainSet
1.ChainedMap
// 1、从 Map 移除所有 配置
clear()
// 2、通过键值从 Map 移除单个配置
delete(key)
// 3、获取 Map 中相应键的值
// 注意:返回值是该 key 对应的值
get(key)
// 4、获取 Map 中相应键的值
// 如果键在 Map 中不存在,则 ChainedMap 中该键的值会被配置为 fn 的返回值.
// 注意:返回值是该 key 对应的值,或者 fn 返回的值
getOrCompute(key, fn)
// 5、配置 Map 中 已存在的键的值
set(key, value)
// 6、Map 中是否存在一个配置值的特定键,
// 注意:返回 boolean
has(key)
// 7、返回 Map 中已存储的所有值的数组
// 注意:返回 Array
values()
// 8、返回 Map 中全部配置的一个对象, 其中 键是这个对象属性,值是相应键的值,
entries()
// 9、 提供一个对象,这个对象的属性和值将 映射进 Map
merge(obj, omit)
// 10、对当前配置上下文执行函数 handler
batch(handler)
// 11、条件执行一个函数去继续配置
// condition: Boolean
// whenTruthy: 当条件为真,调用把 ChainedMap 实例作为单一参数传入的函数
// whenFalsy: 当条件为假,调用把 ChainedMap 实例作为单一参数传入的函数
when(condition, whenTruthy, whenFalsy)
2.ChainSet
// 末尾增加一个值
add(value)
// 在开始位置增加一个值
prepend(value)
// 清空 set 内容
clear()
// 删除某个值
delete(value)
// 判断是否有某个值
has(value)
// 返回值列表
values()
// 合并给定的数组到 Set 尾部。
merge(arr)
// handler: ChainSet => ChainSet
// 一个把 ChainSet 实例作为单个参数的函数
batch(handler)
// condition: Boolean
// whenTruthy: ChainSet -> any, 条件为真时执行
// whenFalsy: ChainSet -> any, 条件为假时执行
when(condition, whenTruthy, whenFalsy)
3.常用方法
1. toString() 调试
config
.module
.rule('compile')
.test(/\.js$/)
.use('babel')
.loader('babel-loader');
config.toString();
// 转换后的输出
{
module: {
rules: [
/* config.module.rule('compile') */
{
test: /\.js$/,
use: [
/* config.module.rule('compile').use('babel') */
{
loader: 'babel-loader'
}
]
}
]
}
}
2. toConfig()导出配置
const Config = require('webpack-chain');
const config = new Config();
console.log(config.toConfig())
3. proxy代理
chainWebpack: config => {
config.devServer.port(8888)
.open(true)
.proxy({'/dev': {
target: 'http://127.0.0.1:80/',
changeOrigin: true,
pathRewrite: {
'^/dev': ''
}
}
})
}
// chain其他队proxy的配置
config.devServer
.host(host)
.hot(hot)
.hotOnly(hotOnly)
.port(port)
.progress(progress)
.proxy(proxy)
.public(public)
.publicPath(publicPath)
4. loader
// 配置一个新的 loader
config.module
.rule('babel')
.test(/\.(js|jsx|mjs|ts|tsx)$/)
.include
.add(path.resolve(__dirname, 'src'))
.end()
.use('babel-loader')
.loader('babel-loader')
.options({
'presets':['@babel/preset-env']
})
// 等同于以下 webpack 配置
module: {
rules: [
{
test: /\.(js|jsx|mjs|ts|tsx)$/,
include: [
path.resolve(__dirname, 'src')
],
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
]
}
}
]
}
]
}
//修改loader
config.module
.rule('ts')
.test(/\.tsx?/)
.use('ts-loader')
.loader('ts-loader')
.tap(option => {
// 一系列
return options;
})
.end()
//移除loader
config.module
.rule('ts')
.test(/\.tsx?/)
.uses.delete('ts-loader')
5. plugin
//新增
//gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = ['js', 'css'];
config.plugin('CompressionWebpackPlugin').use(CompressionWebpackPlugin, [
{
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), // 匹配文件名
threshold: 10240, // 对超过10K的数据进行压缩
minRatio: 0.8, // 极小比
}
]);
//等价于
module.exports = {
plugins:
[new CompressionPlugin(
{
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), // 匹配文件名
threshold: 10240, // 对超过10K的数据进行压缩
minRatio: 0.8, // 极小比
}
)
] };
//移除
config.plugins.delete('CompressionWebpackPlugin')
//插入
const htmlWebpackPlugin = require('html-webpack-plugin');
config.plugin('html')
.use(htmlWebpackPlugin)
.before('extract')
// 使用 tap 方法修改参数
config
.plugin(name)
.tap(args => newArgs)
6. 条件判断
config
.when(process.env.NODE_ENV === 'development', //如果是开发环境
config => {
//在条件里配置 config
}
)
4. vue-cli 中的chain配置
const webpack = require('webpack')
const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = {
publicPath: '/',
outputDir: 'dist',
assetsDir: 'static',
productionSourceMap: false,
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
"/api/": {
target: "http://127.0.0.1:7001",
changeOrigin: true,
pathRewrite: {
'^/api': ""
}
},
}
},
configureWebpack: {
name: name,
resolve: {
alias: {
'@': resolve('src')
}
},
externals: cdn.externals,
},
chainWebpack(config) { //这里使用的是 vue-cli自带的 webpackchain
config.plugin('define').tap(args => {//新增环境变量
args[0]['process.env'].BUILD_ENV = JSON.stringify(process.env.BUILD_ENV)
return args
})
//打开gzip 直接执行
const productionGzipExtensions = ['js', 'css'];
config.plugin('CompressionWebpackPlugin').use(CompressionWebpackPlugin, [
{
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), // 匹配文件名
threshold: 10240, // 对超过10K的数据进行压缩
minRatio: 0.8, // 极小比
}
]);
//当满足条件执行
config
.when(process.env.NODE_ENV === 'production',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
inline: /runtime\..*\.js$/
}])
.end()
//分片优化
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
}
)//条件结束
}//chain配置结束
}
2.configureWebpack
configureWebpack 通过操作对象的形式,来修改默认的 webpack 配置,该对象将会被 webpack-merge 合并入最终的 webpack 配置。
const path = require('path');
function resolve (dir) {
return path.join(__dirname, dir)
}
module.exports = {
devServer: {
...
},
lintOnSave: false, // eslint-loader 是否在保存的时候检查
productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
filenameHashing: true, //文件hash
configureWebpack: config => {
if (isProduction) {
...
} else {
...
}
//返回一个将要合并的对象
return {
resolve: {
alias: {
'@asset':resolve('src/assets')
}
}
}
}
}