Skip to content
New issue

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

feat(plugin-compiler-web): 移除 slot 组件对 class, style 属性的解析以及完善节点返回值校验 #79

18 changes: 18 additions & 0 deletions packages/plugin-compiler-alipay/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,21 @@ export function removeSimilarTarget(t: string): void {
if (t === target) return
SIMILAR_TARGETS.delete(t)
}

/**
* 从 module.exports.xxx 中提取 xxx 变量名
*/
export function getModuleExportsName(content: string): string[] {
const result = []
const regex = /module\.exports\.(\w+)/gim
const matchResult = content.match(regex)

if (!matchResult) return result

matchResult.map((param) => {
const name = param.split('.')[2]
result.push(name)
})

return result
}
57 changes: 56 additions & 1 deletion packages/plugin-compiler-alipay/src/plugins/SjsParserPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
tsTransformerFactory,
typescript as ts
} from '@morjs/utils'
import { isSimilarTarget } from '../constants'
import { getModuleExportsName, isSimilarTarget } from '../constants'

/**
* 支付宝 sjs 文件转译
Expand All @@ -20,6 +20,9 @@ export default class AlipayCompilerSjsParserPlugin implements Plugin {
runner.hooks.beforeRun.tap(this.name, () => {
const { sourceType, target } = runner.userConfig

// 仅当 sjs 是微信时执行该处理
if (sourceType === SourceTypes.wechat)
return this.transformCommonjsToESModule(runner)
// 仅当 sjs 是 支付宝 源码 且 编译目标不是 支付宝小程序 时执行该插件
if (sourceType !== SourceTypes.alipay) return
if (sourceType === target) return
Expand All @@ -44,6 +47,58 @@ export default class AlipayCompilerSjsParserPlugin implements Plugin {
})
}

/**
* 微信转支付宝的场景下 ,wxs 内联文件中使用 module.exports.var 在支付宝中无法正常通过 name.var 调用,
* 需要将这种场景下的导出进行拓展,增加 module.exports = {}, 这样在 webpack 打包时就可以正确导出 export default 文件
*/
transformCommonjsToESModule(runner: Runner) {
runner.hooks.sjsParser.tap(
this.name,
(transformers: ts.CustomTransformers, options) => {
if (
options.fileInfo.content.includes('module.exports.') &&
!(
options.fileInfo.content.includes('module.exports =') ||
options.fileInfo.content.includes('module.exports=')
)
) {
// 提取 module.exports.var 中的变量名
const names = getModuleExportsName(options.fileInfo.content)
if (names.length <= 0 || names.indexOf('default') > -1)
return transformers

transformers.after.push(
tsTransformerFactory((node, ctx) => {
const factory = ctx.factory

if (ts.isSourceFile(node)) {
return factory.updateSourceFile(node, [
...node.statements,
factory.createExportAssignment(
void 0,
void 0,
void 0,
factory.createObjectLiteralExpression(
names.map((name) =>
factory.createShorthandPropertyAssignment(
factory.createIdentifier(name)
)
)
)
)
])
}

return node
})
)
}

return transformers
}
)
}

transformESModuleToCommonjs(transformers: ts.CustomTransformers) {
transformers.before.push(
tsTransformerFactory((node, ctx) => {
Expand Down
17 changes: 17 additions & 0 deletions packages/plugin-compiler-alipay/src/templateProcessorToAlipay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,23 @@ export const templateProcessorToAlipay = {
// 支付宝不支持 大写的标签名, 需要全部转换为小写
if (node.tag) node.tag = node.tag.toLowerCase()

/**
* 如果 sjs name 存在 this,会被转换成 thisSjs,此时如果 node content 中存在 this 调用,
* 将 this 调用转换成 thisSjs 调用
*/
if (
context.sharedContext &&
context.sharedContext.hasSjsModuleAttrNameAsThis
) {
const { content } = node
if (node.content) {
node.content = content.map((c) => {
if (typeof c === 'string') return c.replace(/this\./g, 'thisSjs.')
return c
})
}
}

// 处理双向绑定支持
processTwoWayBinding(node, context)
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IXMLElement } from '../IXmlNode'
import { attributeNode, dataBindingNode, ElementAtrrbute } from '../types'

const AttributesParseer = [
const AttributesParser = [
require('./unsupport/index').default,
require('./event/index').default,
require('./class/index').default,
Expand All @@ -10,13 +10,16 @@ const AttributesParseer = [
require('./slot/index').default
]

export default function (xmlElement: IXMLElement): ElementAtrrbute[] {
function parserAttribute(
xmlElement: IXMLElement,
parser = AttributesParser
): ElementAtrrbute[] {
const attributes: ElementAtrrbute[] = []
if (xmlElement.attributes) {
for (const key of Object.keys(xmlElement.attributes)) {
const value = xmlElement.attributes[key]
let att: ElementAtrrbute
for (const func of AttributesParseer) {
for (const func of parser) {
att = func(key, value)
if (att) {
break
Expand All @@ -32,3 +35,18 @@ export default function (xmlElement: IXMLElement): ElementAtrrbute[] {
}
return attributes
}

export default function (xmlElement: IXMLElement): ElementAtrrbute[] {
return parserAttribute(xmlElement, AttributesParser)
}

const SlotAttributesParser = [
require('./unsupport/index').default,
require('./event/index').default,
require('./ref/index').default,
require('./slot/index').default
]

export function parseSlotAttribute(xmlElement: IXMLElement): ElementAtrrbute[] {
return parserAttribute(xmlElement, SlotAttributesParser)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import parseAttribute from '../../attribute/index'
import { parseSlotAttribute } from '../../attribute/index'
import { attributeValueAndRemove, IXMLElement } from '../../IXmlNode'
import { dataBindingNode, slotNode, SlotNode } from '../../types'
import { parseSubElements } from '../index'
Expand All @@ -10,7 +10,7 @@ export default function (xmlElement: IXMLElement): SlotNode {
node.name = dataBindingNode(
attributeValueAndRemove(xmlElement.attributes, 'name')
)
node.attributes = parseAttribute(xmlElement)
node.attributes = parseSlotAttribute(xmlElement)
}
node.children = parseSubElements(xmlElement)
return node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { DataBindingNode } from '../ast/types'

export function databindingForAttribute(databinding: DataBindingNode) {
if (databinding.hasBinding) {
return t.jsxExpressionContainer(databinding.getExpressionAst())
const ast = databinding.getExpressionAst()
if (ast) return t.jsxExpressionContainer(databinding.getExpressionAst())
return null
} else {
if (databinding.express === undefined) {
return null
Expand Down
1 change: 0 additions & 1 deletion packages/plugin-compiler/src/parsers/sjsParserPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export class SjsParserPlugin implements Plugin {
if (runner.commandName !== COMPILE_COMMAND_NAME) return

const { target, sourceType } = runner.userConfig as CompilerUserConfig

// 如果同源编译,不做处理
if (target === sourceType) return

Expand Down