From bc7b9fbdc69528a8f1986aa48598a2d24494dd8a Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 18 Jan 2022 14:30:54 +0800 Subject: [PATCH] wip(app): nvue --- .../nvue/__snapshots__/compiler.spec.ts.snap | 36 ++++++++++ .../__tests__/nvue/compiler.spec.ts | 39 +++++++---- .../uni-app-vite/src/nvue/plugin/index.ts | 2 + .../plugin/transforms/transformRenderWhole.ts | 1 - .../nvue/plugin/transforms/transformText.ts | 67 +++++++++++++++++++ 5 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 packages/uni-app-vite/__tests__/nvue/__snapshots__/compiler.spec.ts.snap create mode 100644 packages/uni-app-vite/src/nvue/plugin/transforms/transformText.ts diff --git a/packages/uni-app-vite/__tests__/nvue/__snapshots__/compiler.spec.ts.snap b/packages/uni-app-vite/__tests__/nvue/__snapshots__/compiler.spec.ts.snap new file mode 100644 index 000000000..d26e2d67c --- /dev/null +++ b/packages/uni-app-vite/__tests__/nvue/__snapshots__/compiler.spec.ts.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`app-nvue: compiler 1`] = ` +"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" + +export function render(_ctx, _cache) { + return (_openBlock(), _createElementBlock(\\"u-video\\")) +}" +`; + +exports[`app-nvue: compiler 1`] = ` +"import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" + +const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"u-scalable\\", { style: {position:\\"absolute\\",left:\\"0\\",right:\\"0\\",top:\\"0\\",bottom:\\"0\\"} }, [ + /*#__PURE__*/_createElementVNode(\\"view\\") +], -1 /* HOISTED */) +const _hoisted_2 = [ + _hoisted_1 +] + +export function render(_ctx, _cache) { + return (_openBlock(), _createElementBlock(\\"u-video\\", null, _hoisted_2)) +}" +`; + +exports[`app-nvue: compiler hello 1`] = ` +"import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" + +const _hoisted_1 = [\\"appendAsTree\\"] + +export function render(_ctx, _cache) { + return (_openBlock(), _createElementBlock(\\"view\\", null, [ + _createElementVNode(\\"u-text\\", { appendAsTree: true }, \\"hello\\", 8 /* PROPS */, _hoisted_1) + ])) +}" +`; diff --git a/packages/uni-app-vite/__tests__/nvue/compiler.spec.ts b/packages/uni-app-vite/__tests__/nvue/compiler.spec.ts index 18ba700a2..5a1a6a9ef 100644 --- a/packages/uni-app-vite/__tests__/nvue/compiler.spec.ts +++ b/packages/uni-app-vite/__tests__/nvue/compiler.spec.ts @@ -19,9 +19,29 @@ function compile(source: string) { compilerOptions: { ...compilerOptions, }, - }).ast!.children[0] as ElementNode + }) +} + +function genAst(source: string) { + return compile(source).ast!.children[0] as ElementNode } + +function genCode(source: string) { + return compile(source).code +} + +const codes = [ + `hello`, + ``, + ``, +] + describe('app-nvue: compiler', () => { + codes.forEach((code) => { + test(code, () => { + expect(genCode(code)).toMatchSnapshot() + }) + }) test('u-tags', () => { ;[ 'text', @@ -32,24 +52,19 @@ describe('app-nvue: compiler', () => { 'web-view', 'slider', ].forEach((tag) => { - expect(compile(`<${tag}>`).tag).toBe(`u-${tag}`) + expect(genAst(`<${tag}>`).tag).toBe(`u-${tag}`) }) }) - test('video', () => { - expect(compile(``).children.length).toBe(0) - expect( - (compile(``).children[0] as ElementNode).tag - ).toBe('u-scalable') - }) + test('scroll-view', () => { - compile(``) + genAst(``) }) test('render-whole', () => { expect( ( ( findProp( - compile(`hello`), + genAst(`hello`), 'appendAsTree', true, false @@ -60,13 +75,13 @@ describe('app-nvue: compiler', () => { }) test('unitary tag', () => { expect( - findProp(compile(`hello`), 'appendAsTree', true, false) + findProp(genAst(`hello`), 'appendAsTree', true, false) ).toBeTruthy() }) test('tap=>click', () => { expect( ( - findDir(compile(``), 'on')! + findDir(genAst(``), 'on')! .arg as SimpleExpressionNode ).content ).toBe('click') diff --git a/packages/uni-app-vite/src/nvue/plugin/index.ts b/packages/uni-app-vite/src/nvue/plugin/index.ts index 1b3b3c293..417ef2daf 100644 --- a/packages/uni-app-vite/src/nvue/plugin/index.ts +++ b/packages/uni-app-vite/src/nvue/plugin/index.ts @@ -13,6 +13,7 @@ import { nvueOutDir } from '../../utils' import { transformRenderWhole } from './transforms/transformRenderWhole' import { transformAppendAsTree } from './transforms/transformAppendAsTree' import { transformVideo } from './transforms/transformVideo' +import { transformText } from './transforms/transformText' const uTags = { text: 'u-text', image: 'u-image', @@ -27,6 +28,7 @@ export function initNVueNodeTransforms() { // 优先级必须确保 renderWhole > appendAsTree return [ createTransformTag(uTags), + transformText, transformVideo, transformRenderWhole, transformAppendAsTree, diff --git a/packages/uni-app-vite/src/nvue/plugin/transforms/transformRenderWhole.ts b/packages/uni-app-vite/src/nvue/plugin/transforms/transformRenderWhole.ts index 4a5c117ce..79ef95a3b 100644 --- a/packages/uni-app-vite/src/nvue/plugin/transforms/transformRenderWhole.ts +++ b/packages/uni-app-vite/src/nvue/plugin/transforms/transformRenderWhole.ts @@ -5,7 +5,6 @@ export const transformRenderWhole: NodeTransform = (node, _) => { if (!isElementNode(node)) { return } - debugger const prop = findProp(node, 'render-whole') if (!prop) { return diff --git a/packages/uni-app-vite/src/nvue/plugin/transforms/transformText.ts b/packages/uni-app-vite/src/nvue/plugin/transforms/transformText.ts new file mode 100644 index 000000000..bc500eb30 --- /dev/null +++ b/packages/uni-app-vite/src/nvue/plugin/transforms/transformText.ts @@ -0,0 +1,67 @@ +import { isElementNode } from '@dcloudio/uni-cli-shared' +import { + CompoundExpressionNode, + ElementNode, + ElementTypes, + InterpolationNode, + NodeTransform, + NodeTypes, + TemplateChildNode, + TextCallNode, + TextNode, +} from '@vue/compiler-core' + +function isTextNode({ tag }: ElementNode) { + return tag === 'text' || tag === 'u-text' || tag === 'button' +} + +function isText( + node: TemplateChildNode +): node is + | TextNode + | TextCallNode + | InterpolationNode + | CompoundExpressionNode { + const { type } = node + return ( + type === NodeTypes.TEXT || + type === NodeTypes.TEXT_CALL || + type === NodeTypes.INTERPOLATION || + type === NodeTypes.COMPOUND_EXPRESSION + ) +} + +export const transformText: NodeTransform = (node, _) => { + if (!isElementNode(node)) { + return + } + if (isTextNode(node)) { + return + } + const { children } = node + if (!children.length) { + return + } + children.forEach((child, index) => { + if (isText(child)) { + children.splice(index, 1, createText(node, child)) + } + }) +} + +function createText( + parent: ElementNode, + node: TextNode | TextCallNode | InterpolationNode | CompoundExpressionNode +): ElementNode { + return { + tag: 'u-text', + type: NodeTypes.ELEMENT, + tagType: ElementTypes.ELEMENT, + props: [], + isSelfClosing: false, + children: [node], + codegenNode: undefined, + ns: parent.ns, + loc: node.loc, + } +} -- GitLab