We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
工程中有多个目录, 每个目录的 index.js 是一个打包入口. webpack 的打包配置集中在一个公共的目录中. 在编译样式文件时需要根据每个目录入口的一个 xx.json 文件中的某个 flag 决定是否要在 postcss-loader 的配置中添加某个plugin
首先想到的是写一个 webpack plugin, 在 compilation.buildModule 钩子中根据文件的引用路径找到入口 index.js 继而找到 xx.json, 这样根据 json 中的 flag 就可以修改 loader 中的配置
但是 webpack 是多线程打包的, 当编译多个文件时, 修改打包配置钩子会执行多次, 后执行的钩子会把前面钩子改动的配置改掉. 导致编译时的配置可能是错误的. 当然可以通过把 parallelism 参数改为 1 来强制 webpack 一次只编译一个文件. 但是这样做会给后续的维护埋下性能问题
(这段代码只是展示一些查询依赖的思路, 不要在 webpack plugin 中修改打包配置)
/** 找到物料的 index.js */ const findRootModule = (moduleGraph, module) => { let current = module let parent = moduleGraph.getIssuer(current) while (parent) { current = parent parent = moduleGraph.getIssuer(current) } return current } /** 获取物料元数据 */ const findMetadata = (moduleGraph, module) => { const rootModule = findRootModule(moduleGraph, module) const filePath = rootModule.resource const metaFilePath = filePath.replace(/index\.js$/, 'meta.json') return require(metaFilePath) } /** 移除 postcss-pxtorem */ const removePx2Rem = (postcssLoader) => { const { plugins } = postcssLoader.options const pxtoremPluginIndex = plugins.findIndex( (plugin) => plugin.postcssPlugin === 'postcss-pxtorem', ) if (pxtoremPluginIndex !== -1) { plugins.splice(pxtoremPluginIndex, 1) } } class DynamicRemPlugin { constructor(options) { this.options = options } // eslint-disable-next-line class-methods-use-this apply(compiler) { compiler.hooks.compilation.tap('DynamicRemPlugin', (compilation) => { compilation.hooks.buildModule.tap('DynamicRemPlugin', (module) => { const postcssLoader = module.loaders?.find((loader) => loader.loader.includes('postcss-loader'), ) if (!postcssLoader) return const metadata = findMetadata(compilation.moduleGraph, module) if (!metadata.basic?.platform?.includes('H5')) { removePx2Rem(postcssLoader) } }) }) } } module.exports = DynamicRemPlugin
经过查找得知, postcss-loader 的 postcssOptions 可以是一个函数, 函数的入参是当前编译环境的上下文. 这样就可以把之前在钩子中写的逻辑转移到 postcssOptions 中. 这样就不会有配置修改的顺序问题
postcssOptions 作为函数传递的特性在低版本(v3) postcss-loader 中不支持, 目前已知 v7 是支持这个特性的
The text was updated successfully, but these errors were encountered:
No branches or pull requests
需求背景
工程中有多个目录, 每个目录的 index.js 是一个打包入口. webpack 的打包配置集中在一个公共的目录中. 在编译样式文件时需要根据每个目录入口的一个 xx.json 文件中的某个 flag 决定是否要在 postcss-loader 的配置中添加某个plugin
错误思路
首先想到的是写一个 webpack plugin, 在 compilation.buildModule 钩子中根据文件的引用路径找到入口 index.js 继而找到 xx.json, 这样根据 json 中的 flag 就可以修改 loader 中的配置
但是 webpack 是多线程打包的, 当编译多个文件时, 修改打包配置钩子会执行多次, 后执行的钩子会把前面钩子改动的配置改掉. 导致编译时的配置可能是错误的. 当然可以通过把 parallelism 参数改为 1 来强制 webpack 一次只编译一个文件. 但是这样做会给后续的维护埋下性能问题
自定义的 webpack plugin 的代码
(这段代码只是展示一些查询依赖的思路, 不要在 webpack plugin 中修改打包配置)
目前方案
经过查找得知, postcss-loader 的 postcssOptions 可以是一个函数, 函数的入参是当前编译环境的上下文. 这样就可以把之前在钩子中写的逻辑转移到 postcssOptions 中. 这样就不会有配置修改的顺序问题
注意
postcssOptions 作为函数传递的特性在低版本(v3) postcss-loader 中不支持, 目前已知 v7 是支持这个特性的
The text was updated successfully, but these errors were encountered: