vuecli中chainWebpack的常用操作舉例
1、webpack 配置很多,這里我們探討比較經(jīng)常需要修改的:
不復(fù)雜,可以在 configWebpack 中操作:
- mode
- devtool
配置復(fù)雜,可以在 chainWebpack 中操作:
- module.rules
- plugins
- optimization
2、使用 vue inspect 可以查看當(dāng)前 webpack 配置
vue inspect > output.js
配置無非增刪改查四個操作,接下來一一列舉
一、增增加規(guī)則
// loader 默認(rèn)是從下往上處理 // enforce: 決定現(xiàn)有規(guī)則調(diào)用順序 // - pre 優(yōu)先處理 // - normal 正常處理(默認(rèn)) // - inline 其次處理 // - post 最后處理 module.exports = { chainWebpack: config => { config.module .rule('lint') // 定義一個名叫 lint 的規(guī)則 .test(/\.js$/) // 設(shè)置 lint 的匹配正則 .pre() // 指定當(dāng)前規(guī)則的調(diào)用優(yōu)先級 .include // 設(shè)置當(dāng)前規(guī)則的作用目錄,只在當(dāng)前目錄下才執(zhí)行當(dāng)前規(guī)則 .add('src') .end() .use('eslint') // 指定一個名叫 eslint 的 loader 配置 .loader('eslint-loader') // 該配置使用 eslint-loader 作為處理 loader .options({ // 該 eslint-loader 的配置 rules: { semi: 'off' } }) .end() .use('zidingyi') // 指定一個名叫 zidingyi 的 loader 配置 .loader('zidingyi-loader') // 該配置使用 zidingyi-loader 作為處理 loader .options({ // 該 zidingyi-loader 的配置 rules: { semi: 'off' } }) config.module .rule('compile') .test(/\.js$/) .include .add('src') .add('test') .end() .use('babel') .loader('babel-loader') .options({ presets: [ ['@babel/preset-env', { modules: false }] ] }) } }
最后將解析為如下配置:
{ module: { rules: [ /* config.module.rule('lint') */ { test: /\.js$/, enforce: 'pre', include: ['src'], use: [ /* config.module.rule('lint').use('eslint') */ { loader: 'eslint-loader', options: { rules: { semi: 'off' } } }, /* config.module.rule('lint').use('zidingyi') */ { loader: 'zidingyi-loader', options: { rules: { semi: 'off' } } } ] }, /* config.module.rule('compile') */ { test: /\.js$/, include: ['src', 'test'], use: [ /* config.module.rule('compile').use('babel') */ { loader: 'babel-loader', options: { presets: [ ['@babel/preset-env', { modules: false }] ] } } ] } ] } }
增加插件
module.exports = { chainWebpack: config => { // 用法: // config // .plugin(name) // .use(WebpackPlugin, args) // 示例: config .plugin('clean') // 創(chuàng)建一個名稱為 clean 的插件 .use(CleanPlugin, [['dist'], { root: '/dir' }]) // 不要用 new 去創(chuàng)建插件,因為已經(jīng)為你做好了 } }
增加 optimization.minimizers
// 用法(v5版本可用): config.optimization .minimizer(name) .use(WebpackPlugin, args) // 示例: config.optimization .minimizer('css') .use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: { safe: true } }])
二、刪
刪除單個規(guī)則中的全部 loader
// vue.config.js module.exports = { chainWebpack: config => { const svgRule = config.module.rule('svg') // 清除已有規(guī)則 svg 的所有 loader。 // 如果你不這樣做,接下來的 loader 會附加在該規(guī)則現(xiàn)有的 loader 之后。 svgRule.uses.clear() // 添加要替換的 loader svgRule .use('vue-svg-loader') .loader('vue-svg-loader') } }
刪除單個規(guī)則中的一個loader
// 刪除前: { test: /\.m?jsx?$/, exclude: [ function () { /* omitted long function */ } ], use: [ /* config.module.rule('js').use('cache-loader') */ { loader: 'cache-loader', options: { cacheDirectory: 'D:\\webproject\\webapp-jy\\node_modules\\.cache\\babel-loader', cacheIdentifier: '519fc596' } }, /* config.module.rule('js').use('babel-loader') */ { loader: 'babel-loader' } ] } // 刪除后: const jsRule = config.module.rule('js') // 刪除 cache-loader jsRule.uses.delete('cache-loader') { test: /\.m?jsx?$/, exclude: [ function () { /* omitted long function */ } ], use: [ /* config.module.rule('js').use('babel-loader') */ { loader: 'babel-loader' } ] }
刪除單個規(guī)則
const moduleRule = config.module // 刪除命名為 js 的規(guī)則 moduleRule.rules.delete('js')
刪除插件
config.plugins.delete(name)
刪除 optimization.minimizers
config.optimization.minimizers.delete(name)
三、改
修改單個 loader 的配置
// 兩種寫法都可修改 config.module .rule('compile') .use('babel') .tap(options => merge(options, { plugins: ['@babel/plugin-proposal-class-properties'] })) config.module .rule('compile') .use('babel') .loader('babel-loader') .tap(options => merge(options, { plugins: ['@babel/plugin-proposal-class-properties'] }))
在多個 loader 中進(jìn)行添加或者刪除
config.module.rule('js').toConfig(): // { // test: /\.m?jsx?$/, // exclude: [ [Function] ], // use: [ // { loader: 'cache-loader', options: [Object] }, // { loader: 'babel-loader' } // ] // } // 這里以添加一個新的 loader 為例 // 1、拿到原來的 loader let originUse = config.module.rule('js').toConfig().use // 2、添加 loader let newLoader = { loader: 'eslint-loader' } originUse.splice(1, 0, newLoader) // 3、清空原來的 loader config.module.rule('js').uses.clear() // 4、重新設(shè)置新的 loader config.module.rule('js').merge({ use: originUse}) // { // test: /\.m?jsx?$/, // exclude: [ [Function] ], // use: [ // { loader: 'cache-loader', options: [Object] }, // { loader: 'eslint-loader' }, // { loader: 'babel-loader' } // ] // }
修改插件參數(shù)
// 用法: config.plugin(name) .tap(args => newArgs) // 示例: config.plugin('env') .tap(args => [...args, 'SECRET_KEY']) // 修改前: /* config.plugin('optimize-css') */ new OptimizeCssnanoPlugin( { sourceMap: false, cssnanoOptions: { preset: [ 'default', { mergeLonghand: false, cssDeclarationSorter: false } ] }, } ) // 修改后: config.plugin('optimize-css') .tap(args => { args[0].yy = 1 return args }) /* config.plugin('optimize-css') */ new OptimizeCssnanoPlugin( { sourceMap: false, cssnanoOptions: { preset: [ 'default', { mergeLonghand: false, cssDeclarationSorter: false } ] }, yy: 2 } ) config.plugin('optimize-css') .tap(args => { return [...args, { x: 1 }] }) /* config.plugin('optimize-css') */ new OptimizeCssnanoPlugin( { sourceMap: false, cssnanoOptions: { preset: [ 'default', { mergeLonghand: false, cssDeclarationSorter: false } ] } }, { x: 1 } )
修改插件實例
config.plugin(name) .init((Plugin, args) => new Plugin(...args))
修改插件調(diào)用順序
指定當(dāng)前插件上下文應(yīng)該在另一個指定插件之前/之后執(zhí)行,你不能在同一個插件上同時使用 .before() 和 .after()
// 用法: // 在 otherName 之前調(diào)用 config .plugin(name) .before(otherName) // 在 otherName 之后調(diào)用 config .plugin(name) .after(otherName) // 示例: // 修改之前: [ /* config.plugin('named-chunks') */ new NamedChunksPlugin( function () { /* omitted long function */ } ), /* config.plugin('copy') */ new CopyWebpackPlugin( [] ) ] // 修改后: config.plugin('named-chunks') .after('copy') [ /* config.plugin('copy') */ new CopyWebpackPlugin( [] ), /* config.plugin('named-chunks') */ new NamedChunksPlugin( function () { /* omitted long function */ } ) ] config.plugin('copy') .before('named-chunks') [ /* config.plugin('copy') */ new CopyWebpackPlugin( [] ), /* config.plugin('named-chunks') */ new NamedChunksPlugin( function () { /* omitted long function */ } ) ]
修改 optimization
// 用法(v5版本可用): config.optimization .minimizer(name) .tap(args => newArgs) // 示例: config.optimization .minimizer('css') .tap(args => [...args, { cssProcessorOptions: { safe: false } }])
四、查
使用 .toConfig()
輸出配置
// 示例1: console.log('js config :>> ', config.module.rule('js').toConfig()) js config :>> { test: /\.m?jsx?$/, exclude: [ [Function] ], use: [ { loader: 'cache-loader', options: [Object] }, { loader: 'babel-loader' } ] } // *************************** // 示例2: console.log('cache-loader config :>> ', config.module.rule('js').use('cache-loader').toConfig()) cache-loader config :>> { loader: 'cache-loader', options: { cacheDirectory: 'D:\\webproject\\myproject\\node_modules\\.cache\\babel-loader', cacheIdentifier: '20a97f42' } } // *************************** // 示例3: console.log('plugin config :>> ', config.plugin('optimize-css').toConfig()) plugin config :>> OptimizeCssnanoPlugin { options: { sourceMap: false, cssnanoOptions: { preset: [Array] } } }
五、操作方法
chainWebpack 中,有兩個大的數(shù)據(jù)分類:ChainedMap
和 ChainedSet
在操作的時候分別有如下方法可以鏈?zhǔn)秸{(diào)用:
ChainedMap:
// 從 Map 移除所有 配置. clear() // 通過鍵值從 Map 移除單個配置. // key: * delete(key) // 獲取 Map 中相應(yīng)鍵的值 // key: * // returns: value get(key) // 獲取 Map 中相應(yīng)鍵的值 // 如果鍵在Map中不存在,則ChainedMap中該鍵的值會被配置為fn的返回值. // key: * // fn: Function () -> value // returns: value getOrCompute(key, fn) // 配置Map中 已存在的鍵的值 // key: * // value: * set(key, value) // Map中是否存在一個配置值的特定鍵,返回 真或假 // key: * // returns: Boolean has(key) // 返回 Map中已存儲的所有值的數(shù)組 // returns: Array values() // 返回Map中全部配置的一個對象, 其中 鍵是這個對象屬性,值是相應(yīng)鍵的值, // 如果Map是空,返回 `undefined` // 使用 `.before() 或 .after()` 的ChainedMap, 則將按照屬性名進(jìn)行排序。 // returns: Object, undefined if empty entries() // 提供一個對象,這個對象的屬性和值將 映射進(jìn) Map。 // 你也可以提供一個數(shù)組作為第二個參數(shù)以便忽略合并的屬性名稱。 // obj: Object // omit: Optional Array merge(obj, omit) // 對當(dāng)前配置上下文執(zhí)行函數(shù)。 // handler: Function -> ChainedMap // 一個把ChainedMap實例作為單個參數(shù)的函數(shù) batch(handler) // 條件執(zhí)行一個函數(shù)去繼續(xù)配置 // condition: Boolean // whenTruthy: Function -> ChainedMap // 當(dāng)條件為真,調(diào)用把ChainedMap實例作為單一參數(shù)傳入的函數(shù) // whenFalsy: Optional Function -> ChainedMap // 當(dāng)條件為假,調(diào)用把ChainedMap實例作為單一參數(shù)傳入的函數(shù) when(condition, whenTruthy, whenFalsy)
ChainedSet:
// 添加/追加 給Set末尾位置一個值. // value: * add(value) // 添加 給Set開始位置一個值. // value: * prepend(value) // 移除Set中全部值. clear() // 移除Set中一個指定的值. // value: * delete(value) // 檢測Set中是否存在一個值. // value: * // returns: Boolean has(value) // 返回Set中值的數(shù)組. // returns: Array values() // 連接給定的數(shù)組到 Set 尾部。 // arr: Array merge(arr) // 對當(dāng)前配置上下文執(zhí)行函數(shù)。 // handler: Function -> ChainedSet // 一個把 ChainedSet 實例作為單個參數(shù)的函數(shù) batch(handler) // 條件執(zhí)行一個函數(shù)去繼續(xù)配置 // condition: Boolean // whenTruthy: Function -> ChainedSet // 當(dāng)條件為真,調(diào)用把 ChainedSet 實例作為單一參數(shù)傳入的函數(shù) // whenFalsy: Optional Function -> ChainedSet // 當(dāng)條件為假,調(diào)用把 ChainedSet 實例作為單一參數(shù)傳入的函數(shù) when(condition, whenTruthy, whenFalsy)
更多配置操作,參考中文文檔
總結(jié)
到此這篇關(guān)于vuecli中chainWebpack的常用操作舉例的文章就介紹到這了,更多相關(guān)vuecli中chainWebpack操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?mounted周期中document.querySelectorAll()獲取不到元素的解決
這篇文章主要介紹了vue?mounted周期中document.querySelectorAll()獲取不到元素的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03