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')
        }
      }
    } 
  }
} 

posted on 2024-08-27 11:32  ygunoil  阅读(357)  评论(0编辑  收藏  举报