vue-cli/webpack4.x 打包--webpack配置--chainWebpack

webpack-chain是啥

针对Webpack的流式配置方案

webpack-chain优势

 

  1. 动态修改配置信息
  2. 链式调用,避免深层的嵌套配置
  3. 跨项目共享 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)


对于ChainSetChainMap对象都有条件配置方法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也是一个比较庞大的对象,参照官方文档:

 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

 

 
posted @ 2023-03-31 14:55  混名汪小星  阅读(1757)  评论(0编辑  收藏  举报