diff --git a/docs-vuepress/api/compile.md b/docs-vuepress/api/compile.md index c707187c28..b6bc98a559 100644 --- a/docs-vuepress/api/compile.md +++ b/docs-vuepress/api/compile.md @@ -707,6 +707,41 @@ module.exports = defineConfig({ }) ``` +**注意:**默认添加的 postcss 插件均会在`mpx的内置插件`(例如如rpx插件等)之后处理。如需使配置的插件优先于内置插件,可以在 `postcssInlineConfig` 中添加 `mpxPrePlugins` 配置: + +```js +// vue.config.js +module.exports = defineConfig({ + pluginOptions: { + mpx: { + plugin: { + postcssInlineConfig: { + plugins: [ + require('postcss-import'), + require('postcss-preset-env'), + ], + mpxPrePlugins: [ + require('cssnano'), + require('autoprefixer') + ] + // 以下写法同理 + // mpxPrePlugins: { + // 'cssnano': {}, + // 'autoprefixer': {} + // } + } + } + } + } +}) +``` + +在上面这个例子当中,postcss 插件处理的最终顺序为:`cssnano` -> `autoprefixer` -> `mpx内置插件` -> `postcss-import` -> `postcss-preset-env` + +::: warning +注意:在 `mpxPrePlugins` 中配置的 postcss 插件如果不通过 mpx 进行处理,那么将不会生效。 +::: + ### decodeHTMLText `boolean = false` diff --git a/packages/webpack-plugin/lib/style-compiler/index.js b/packages/webpack-plugin/lib/style-compiler/index.js index 82835caeb3..760397aac2 100644 --- a/packages/webpack-plugin/lib/style-compiler/index.js +++ b/packages/webpack-plugin/lib/style-compiler/index.js @@ -82,9 +82,9 @@ module.exports = function (css, map) { } } - plugins.push(...config.plugins) // push user config plugins + const finalPlugins = config.prePlugins.concat(plugins, config.plugins) - return postcss(plugins) + return postcss(finalPlugins) .process(css, options) .then(result => { // ali环境添加全局样式抹平root差异 diff --git a/packages/webpack-plugin/lib/style-compiler/load-postcss-config.js b/packages/webpack-plugin/lib/style-compiler/load-postcss-config.js index cc94f28756..093b79cfd1 100644 --- a/packages/webpack-plugin/lib/style-compiler/load-postcss-config.js +++ b/packages/webpack-plugin/lib/style-compiler/load-postcss-config.js @@ -1,4 +1,5 @@ const load = require('postcss-load-config') +const loadPlugins = require('postcss-load-config/src/plugins') let loaded @@ -28,19 +29,26 @@ module.exports = function loadPostcssConfig (loaderContext, inlineConfig = {}) { }) } - return loaded.then(config => { + return loaded.then((config = {}) => { let plugins = inlineConfig.plugins || [] let options = inlineConfig.options || {} + let prePlugins = inlineConfig.prePlugins || [] // merge postcss config file - if (config && config.plugins) { + if (config.plugins) { plugins = plugins.concat(config.plugins) } - if (config && config.options) { + if (config.options) { + if (config.options.mpxPrePlugins) { + // 使入参和postcss格式保持一致 + prePlugins = prePlugins.concat(loadPlugins({ plugins: config.options.mpxPrePlugins }, config.file)) + delete config.options.mpxPrePlugins + } options = Object.assign({}, config.options, options) } return { + prePlugins, plugins, options } diff --git a/packages/webpack-plugin/lib/template-compiler/bind-this.js b/packages/webpack-plugin/lib/template-compiler/bind-this.js index 3209fc31d6..b50be9df02 100644 --- a/packages/webpack-plugin/lib/template-compiler/bind-this.js +++ b/packages/webpack-plugin/lib/template-compiler/bind-this.js @@ -121,24 +121,19 @@ function checkDelAndGetPath (path) { } if (t.isLogicalExpression(container)) { // case: a || ((b || c) && d) - ignore = true - break - } - - // case: a ??= b - if ( - key === 'right' && - t.isAssignmentExpression(container) && - ['??=', '||=', '&&='].includes(container.operator) - ) { + canDel = false ignore = true break } if (t.isConditionalExpression(container)) { - if (key === 'test') canDel = false - else ignore = true - break + if (key === 'test') { + canDel = false + break + } else { + ignore = true + replace = true + } } if ( @@ -229,11 +224,10 @@ module.exports = { // 删除局部作用域的变量 if (scopeBinding) { if (renderReduce) { - const { delPath, canDel, ignore, replace } = checkDelAndGetPath(path) - if (canDel && !ignore) { + const { delPath, canDel, replace } = checkDelAndGetPath(path) + if (canDel) { delPath.delInfo = { isLocal: true, - canDel, replace } } @@ -252,14 +246,16 @@ module.exports = { if (!renderReduce) return const { delPath, canDel, ignore, replace } = checkDelAndGetPath(path) - if (ignore) return - delPath.delInfo = { - keyPath, - canDel, - replace + if (canDel) { + delPath.delInfo = { + keyPath, + replace + } } + if (ignore) return // ignore不计数,不需要被统计 + const { bindings } = bindingsMap.get(currentBlock) const target = bindings[keyPath] || [] target.push({ @@ -310,28 +306,26 @@ module.exports = { enter (path) { // 删除重复变量 if (path.delInfo) { - const { keyPath, canDel, isLocal, replace } = path.delInfo + const { keyPath, isLocal, replace } = path.delInfo delete path.delInfo - if (canDel) { - if (isLocal) { // 局部作用域里的变量,可直接删除 - dealRemove(path, replace) - return - } - const data = bindingsMap.get(currentBlock) - const { bindings, pBindings } = data - const allBindings = Object.assign({}, pBindings, bindings) - - // 优先判断前缀,再判断全等 - if (checkPrefix(Object.keys(allBindings), keyPath) || pBindings[keyPath]) { - dealRemove(path, replace) - } else { - const currentBlockVars = bindings[keyPath] - if (currentBlockVars.length > 1) { - const index = currentBlockVars.findIndex(item => !item.canDel) - if (index !== -1 || currentBlockVars[0].path !== path) { // 当前block中存在不可删除的变量 || 不是第一个可删除变量,即可删除该变量 - dealRemove(path, replace) - } + if (isLocal) { // 局部作用域里的变量,可直接删除 + dealRemove(path, replace) + return + } + const data = bindingsMap.get(currentBlock) + const { bindings, pBindings } = data + const allBindings = Object.assign({}, pBindings, bindings) + + // 优先判断前缀,再判断全等 + if (checkPrefix(Object.keys(allBindings), keyPath) || pBindings[keyPath]) { + dealRemove(path, replace) + } else { + const currentBlockVars = bindings[keyPath] || [] // 对于只出现一次的可忽略变量,需要兜底 + if (currentBlockVars.length >= 1) { + const index = currentBlockVars.findIndex(item => !item.canDel) + if (index !== -1 || currentBlockVars[0].path !== path) { // 当前block中存在不可删除的变量 || 不是第一个可删除变量,即可删除该变量 + dealRemove(path, replace) } } } diff --git a/packages/webpack-plugin/test/platform/common/bind-this.spec.js b/packages/webpack-plugin/test/platform/common/bind-this.spec.js index c200e0e272..aff00108dc 100644 --- a/packages/webpack-plugin/test/platform/common/bind-this.spec.js +++ b/packages/webpack-plugin/test/platform/common/bind-this.spec.js @@ -64,14 +64,14 @@ global.currentInject.render = function (_i, _c, _r, _sc) { _sc("b"); _sc("c"); - _sc("a") ? _sc("b") : _sc("c"); + _sc("a") ? "" : ""; _sc("a") && _sc("b"); _sc("d"); _sc("e"); - _sc("a") ? _sc("d") : _sc("e"); + _sc("a") ? "" : ""; if (_sc("f") + _sc("g")) {} @@ -163,6 +163,18 @@ global.currentInject.render = function (_i, _c, _r, _sc) { a4 a4 || '' || '' + + a5 + b5 + c5 + a5 && b5 + if (a5 && b5) {} + if (a5 ? b5 : c5) {} + + a6 ? b6 : c6 // b6 c6只出现一次,不会被删除 + + b7 + a7 ? b7.name : c7 obj8 obj8 + 'rpx' @@ -209,6 +221,21 @@ global.currentInject.render = function (_i, _c, _r, _sc) { _sc("a4"); + _sc("b5"); + + _sc("c5"); + + _sc("a5") && _sc("b5"); + + if (_sc("a5") && _sc("b5")) {} + + if (_sc("a5") ? _sc("b5") : _sc("c5")) {} + + _sc("a6") ? _sc("b6") : _sc("c6"); // b6 c6只出现一次,不会被删除 + + _sc("b7"); + _sc("a7") ? "" : _sc("c7"); + _sc("obj8"); "" + 'rpx'; 'height:' + "" + 'rpx'; @@ -288,7 +315,7 @@ global.currentInject.render = function (_i, _c, _r, _sc) { const output = ` global.currentInject.render = function (_i, _c, _r, _sc) { this._i(this.list, function (item, index) { - item.a ? "" : item.b; + item.a ? "" : ""; item.a || item.b; }); };`