使用webpack-merge合并配置后如何在编译前移除重复module rule?
解决方案
方法1:使用webpack-merge自带的自定义合并策略(最推荐)
webpack-merge本身支持自定义合并规则,不需要修改原有配置结构,直接针对module.rules字段做特殊处理即可,开发环境合并时直接淘汰公共配置中重复的js/ts规则:
const { mergeWithCustomize } = require('webpack-merge'); const commonConfig = require('./webpack.common.js'); const devConfig = require('./webpack.dev.js'); module.exports = mergeWithCustomize({ customizeArray(commonArr, devArr, key) { // 仅对module.rules做自定义合并 if (key === 'module.rules') { // 先筛掉公共配置中匹配js/ts的旧规则 const filteredCommonRules = commonArr.filter(rule => { return rule.test.toString() !== /\.(ts|js)x?$/.toString() }) // 合并保留开发环境的js/ts规则和其他公共规则 return [...filteredCommonRules, ...devArr] } // 其余字段走默认合并逻辑 return undefined } })(commonConfig, devConfig)
方法2:合并后手动过滤重复规则
如果不想修改合并逻辑,也可以在得到合并后的配置后,直接对规则数组做去重处理:
const { merge } = require('webpack-merge'); const commonConfig = require('./webpack.common.js'); const devConfig = require('./webpack.dev.js'); const mergedConfig = merge(commonConfig, devConfig); // 对规则数组做去重,仅保留带react-refresh的js/ts规则(开发环境) mergedConfig.module.rules = mergedConfig.module.rules.reduce((result, currentRule) => { const testRegStr = currentRule.test.toString() // 非js/ts规则直接保留 if (testRegStr !== /\.(ts|js)x?$/.toString()) { result.push(currentRule) return result } // js/ts规则只保留带react-refresh配置的 const hasRefreshPlugin = currentRule.use.some(loaderItem => { return loaderItem.options?.plugins?.some?.(plugin => plugin.includes('react-refresh/babel') ) }) if (hasRefreshPlugin) { result.push(currentRule) } return result }, []) module.exports = mergedConfig
不需要用到webpack hooks,在配置导出为对象前处理是最直接的方案,webpack会直接读取你最终导出的配置执行编译。如果是生产环境合并,反过来保留不带react-refresh的规则即可。
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

