From c134b5f2ccfbf446fcdc262a8f076333bb74656b Mon Sep 17 00:00:00 2001 From: qiang Date: Thu, 16 Jun 2022 16:42:21 +0800 Subject: [PATCH] feat(mp): config add mergeVirtualHostAttributes --- .../lib/script/traverse/data/class.js | 12 ++++------- .../lib/script/traverse/data/style.js | 20 +++++++++---------- .../lib/script/traverse/data/util.js | 7 +------ .../lib/script/traverse/visitor.js | 8 ++++++-- .../lib/template/generate.js | 9 ++++++--- packages/uni-template-compiler/lib/util.js | 11 ++++++++-- packages/vue-cli-plugin-uni/lib/env.js | 2 ++ .../webpack-uni-mp-loader/lib/template.js | 3 ++- packages/webpack-uni-pages-loader/lib/util.js | 3 ++- 9 files changed, 42 insertions(+), 33 deletions(-) diff --git a/packages/uni-template-compiler/lib/script/traverse/data/class.js b/packages/uni-template-compiler/lib/script/traverse/data/class.js index 572d6b0e2..6b77e46fc 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/class.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/class.js @@ -6,12 +6,9 @@ const { } = require('../../../constants') const { - getCode -} = require('../../../util') - -const { + getCode, isRootElement -} = require('./util') +} = require('../../../util') function processClassArrayExpressionElements (classArrayExpression) { let binaryExpression @@ -84,8 +81,7 @@ function processClassArrayExpression (classValuePath) { module.exports = function processClass (paths, path, state) { const classPath = paths.class const staticClassPath = paths.staticClass - const platformName = state.options.platform.name - const virtualHost = platformName === 'mp-weixin' || platformName === 'mp-alipay' + const mergeVirtualHostAttributes = state.options.mergeVirtualHostAttributes let classArrayExpression if (classPath) { const classValuePath = classPath.get('value') @@ -128,7 +124,7 @@ module.exports = function processClass (paths, path, state) { state.errors.add(':class' + uniI18n.__('templateCompiler.noSupportSyntax', { 0: getCode(classValuePath.node) })) } } - if (virtualHost && isRootElement(path.parentPath)) { + if (mergeVirtualHostAttributes && isRootElement(path.parentPath)) { const virtualHostClass = t.identifier(VIRTUAL_HOST_CLASS) if (classArrayExpression) { classArrayExpression.elements.push(virtualHostClass) diff --git a/packages/uni-template-compiler/lib/script/traverse/data/style.js b/packages/uni-template-compiler/lib/script/traverse/data/style.js index 0ea6d8977..657e87953 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/style.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/style.js @@ -8,12 +8,9 @@ const { const { getCode, - hyphenate -} = require('../../../util') - -const { + hyphenate, isRootElement -} = require('./util') +} = require('../../../util') const getMemberExpr = require('../member-expr') @@ -125,8 +122,7 @@ function generateGetStyle (stylePath, styleValuePath, staticStylePath, state) { module.exports = function processStyle (paths, path, state) { const stylePath = paths.style const staticStylePath = paths.staticStyle - const platformName = state.options.platform.name - const virtualHost = platformName === 'mp-weixin' || platformName === 'mp-alipay' + const mergeVirtualHostAttributes = state.options.mergeVirtualHostAttributes if (stylePath) { const styleValuePath = stylePath.get('value') if (styleValuePath.isObjectExpression()) { @@ -177,18 +173,22 @@ module.exports = function processStyle (paths, path, state) { } else { state.errors.add(`:style 不支持 ${getCode(styleValuePath.node)} 语法`) } - if (virtualHost && isRootElement(path.parentPath)) { + if (mergeVirtualHostAttributes && isRootElement(path.parentPath)) { styleValuePath.replaceWith(t.binaryExpression('+', styleValuePath.node, t.identifier(VIRTUAL_HOST_STYLE))) } } else if (staticStylePath) { - if (virtualHost && isRootElement(path.parentPath)) { + if (mergeVirtualHostAttributes && isRootElement(path.parentPath)) { const styleNode = processStaticStyle([t.identifier(VIRTUAL_HOST_STYLE)], staticStylePath, state) - const property = t.objectProperty(t.identifier('style'), styleNode) path.node.properties.push(property) return [] } staticStylePath.get('value').replaceWith(getStaticStyleStringLiteral(staticStylePath, state)) + } else { + if (mergeVirtualHostAttributes && isRootElement(path.parentPath)) { + const property = t.objectProperty(t.identifier('style'), t.identifier(VIRTUAL_HOST_STYLE)) + path.node.properties.push(property) + } } return [] } diff --git a/packages/uni-template-compiler/lib/script/traverse/data/util.js b/packages/uni-template-compiler/lib/script/traverse/data/util.js index d6f41e6ce..e666ca086 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/util.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/util.js @@ -2,8 +2,7 @@ const t = require('@babel/types') const babelTraverse = require('@babel/traverse').default const { - INTERNAL_SET_MODEL, - METHOD_CREATE_ELEMENT + INTERNAL_SET_MODEL } = require('../../../constants') module.exports = { @@ -44,9 +43,5 @@ module.exports = { ] ) ) - }, - isRootElement (path) { - const result = path.findParent(path => (path.isCallExpression() && path.get('callee').isIdentifier({ name: METHOD_CREATE_ELEMENT })) || path.isReturnStatement()) - return result.isReturnStatement() } } diff --git a/packages/uni-template-compiler/lib/script/traverse/visitor.js b/packages/uni-template-compiler/lib/script/traverse/visitor.js index 3480728c7..fcf1bcc77 100644 --- a/packages/uni-template-compiler/lib/script/traverse/visitor.js +++ b/packages/uni-template-compiler/lib/script/traverse/visitor.js @@ -24,7 +24,8 @@ const { hyphenate, traverseFilter, getComponentName, - hasEscapeQuote + hasEscapeQuote, + isRootElement } = require('../../util') const traverseData = require('./data') @@ -182,7 +183,10 @@ module.exports = { if (this.options.scopeId) { addStaticClass(path, this.options.scopeId) } - + // 根节点无 attrs 时添加空对象,方便后续合并外层 attrs + if (this.options.mergeVirtualHostAttributes && !t.isObjectExpression(path.node.arguments[1]) && isRootElement(path)) { + path.node.arguments.splice(1, 0, t.objectExpression([])) + } const dataPath = path.get('arguments.1') dataPath && dataPath.isObjectExpression() && traverseData(dataPath, this, tagNode.value) } diff --git a/packages/uni-template-compiler/lib/template/generate.js b/packages/uni-template-compiler/lib/template/generate.js index 64b88e5fa..b2f320d4e 100644 --- a/packages/uni-template-compiler/lib/template/generate.js +++ b/packages/uni-template-compiler/lib/template/generate.js @@ -13,7 +13,7 @@ const uniI18n = require('@dcloudio/uni-cli-i18n') function processElement (ast, state, isRoot) { const platform = state.options.platform const platformName = platform.name - const virtualHost = platformName === 'mp-weixin' || platformName === 'mp-alipay' + const mergeVirtualHostAttributes = state.options.mergeVirtualHostAttributes // if (ast.type === 'template' && hasOwn(ast.attr, 'slot')) { ast.type = 'view' @@ -47,13 +47,16 @@ function processElement (ast, state, isRoot) { ast.attr['bind:' + INTERNAL_EVENT_LINK] = INTERNAL_EVENT_LINK } - if (virtualHost && platform.isComponent(ast.type)) { + if (mergeVirtualHostAttributes && platform.isComponent(ast.type)) { const obj = { style: VIRTUAL_HOST_STYLE, class: VIRTUAL_HOST_CLASS } Object.keys(obj).forEach(key => { - ast.attr[obj[key]] = ast.attr[key] + if (key in ast.attr) { + ast.attr[obj[key]] = ast.attr[key] + } + // 支付宝小程序自定义组件外部属性始终无效 if (platformName === 'mp-alipay') { delete ast.attr[key] } diff --git a/packages/uni-template-compiler/lib/util.js b/packages/uni-template-compiler/lib/util.js index ea35f9c70..b1db3b2d2 100644 --- a/packages/uni-template-compiler/lib/util.js +++ b/packages/uni-template-compiler/lib/util.js @@ -5,7 +5,8 @@ const uniI18n = require('@dcloudio/uni-cli-i18n') const { METHOD_RENDER_LIST, - METHOD_RESOLVE_SCOPED_SLOTS + METHOD_RESOLVE_SCOPED_SLOTS, + METHOD_CREATE_ELEMENT } = require('./constants') function cached (fn) { @@ -270,6 +271,11 @@ function hasEscapeQuote (path) { return has } +function isRootElement (path) { + const result = path.findParent(path => (path.isCallExpression() && path.get('callee').isIdentifier({ name: METHOD_CREATE_ELEMENT })) || path.isReturnStatement()) + return result.isReturnStatement() +} + module.exports = { hasOwn, isUnaryTag: makeMap( @@ -301,5 +307,6 @@ module.exports = { processMemberExpression, getForIndexIdentifier, isSimpleObjectExpression, - hasEscapeQuote + hasEscapeQuote, + isRootElement } diff --git a/packages/vue-cli-plugin-uni/lib/env.js b/packages/vue-cli-plugin-uni/lib/env.js index f98a50abd..d5c46ceee 100644 --- a/packages/vue-cli-plugin-uni/lib/env.js +++ b/packages/vue-cli-plugin-uni/lib/env.js @@ -319,6 +319,8 @@ if ((process.env.UNI_PLATFORM === 'mp-kuaishou' || process.env.UNI_PLATFORM === process.env.SCOPED_SLOTS_COMPILER = modes[2] } +process.env.MERGE_VIRTUAL_HOST_ATTRIBUTES = (!!platformOptions.mergeVirtualHostAttributes).toString() + process.env.UNI_STAT_UNI_CLOUD = '' process.env.UNI_STAT_DEBUG = '' if ( diff --git a/packages/webpack-uni-mp-loader/lib/template.js b/packages/webpack-uni-mp-loader/lib/template.js index 68f05ea92..6f31c6f39 100644 --- a/packages/webpack-uni-mp-loader/lib/template.js +++ b/packages/webpack-uni-mp-loader/lib/template.js @@ -66,7 +66,8 @@ module.exports = function (content, map) { Object.assign(vueLoaderOptions.options.compilerOptions, { mp: { platform: process.env.UNI_PLATFORM, - scopedSlotsCompiler: process.env.SCOPED_SLOTS_COMPILER + scopedSlotsCompiler: process.env.SCOPED_SLOTS_COMPILER, + mergeVirtualHostAttributes: process.env.MERGE_VIRTUAL_HOST_ATTRIBUTES === 'true' }, filterModules, filterTagName, diff --git a/packages/webpack-uni-pages-loader/lib/util.js b/packages/webpack-uni-pages-loader/lib/util.js index 6b5d22e1b..1bfdf500a 100644 --- a/packages/webpack-uni-pages-loader/lib/util.js +++ b/packages/webpack-uni-pages-loader/lib/util.js @@ -136,7 +136,8 @@ const NON_APP_JSON_KEYS = [ 'optimization', 'scopedSlotsCompiler', 'usingComponents', - 'uniStatistics' + 'uniStatistics', + 'mergeVirtualHostAttributes' ] module.exports = { hasOwn, -- GitLab