From: 三咲智子 Kevin Deng Date: Fri, 24 Nov 2023 03:07:31 +0000 (+0800) Subject: refactor: helpers, import type, cleanup X-Git-Tag: v3.6.0-alpha.1~16^2~834 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d02629efa261c8959ebe9e903332bfab4905828f;p=thirdparty%2Fvuejs%2Fcore.git refactor: helpers, import type, cleanup --- diff --git a/packages/compiler-vapor/__tests__/__snapshots__/basic.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/basic.test.ts.snap index c00e8dbc71..efb1dbb7b3 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/basic.test.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/basic.test.ts.snap @@ -3,7 +3,7 @@ exports[`basic 1`] = ` "import { defineComponent as _defineComponent } from 'vue' import { watchEffect } from 'vue' -import { template, setAttr, setText, children, on, insert } from 'vue/vapor' +import { template, insert, setText, on } from 'vue/vapor' const t0 = template(\`

Counter

Count:

Double:

\`) import { ref, computed } from 'vue' diff --git a/packages/compiler-vapor/src/compile.ts b/packages/compiler-vapor/src/compile.ts index 3c50396d4b..d31dad374e 100644 --- a/packages/compiler-vapor/src/compile.ts +++ b/packages/compiler-vapor/src/compile.ts @@ -1,7 +1,7 @@ import { - CodegenResult, - CompilerOptions, - RootNode, + type CodegenResult, + type CompilerOptions, + type RootNode, baseParse, } from '@vue/compiler-dom' import { isString } from '@vue/shared' diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index d809d093ce..8169678ace 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -1,9 +1,9 @@ -import { +import type { CodegenContext, CodegenOptions, CodegenResult, } from '@vue/compiler-dom' -import { DynamicChildren, IRNodeTypes, RootIRNode } from './transform' +import { type DynamicChildren, type RootIRNode, IRNodeTypes } from './ir' // IR -> JS codegen export function generate( @@ -13,26 +13,28 @@ export function generate( } = {}, ): CodegenResult { let code = '' - let preamble = `import { watchEffect } from 'vue' -import { template, setAttr, setText, children, on, insert } from 'vue/vapor'\n` + let preamble = '' - const isSetupInlined = !!options.inline - - preamble += ir.template - .map((template, i) => `const t${i} = template(\`${template.template}\`)\n`) - .join('') + const { helpers, vaporHelpers } = ir + if (ir.template.length) { + preamble += ir.template + .map( + (template, i) => `const t${i} = template(\`${template.template}\`)\n`, + ) + .join('') + vaporHelpers.add('template') + } code += `const root = t0()\n` - if (ir.children[0]) { - code += `const {${genChildrens( - ir.children[0].children, - )}} = children(root)\n` + code += `const {${genChildren(ir.children[0].children)}} = children(root)\n` + vaporHelpers.add('children') } for (const opration of ir.opration) { switch (opration.type) { case IRNodeTypes.TEXT_NODE: { + // TODO handle by runtime: document.createTextNode code += `const n${opration.id} = document.createTextNode(${opration.content})\n` break } @@ -46,6 +48,7 @@ import { template, setAttr, setText, children, on, insert } from 'vue/vapor'\n` anchor = `, 0 /* InsertPosition.FIRST */` } code += `insert(n${opration.element}, n${opration.parent}${anchor})\n` + vaporHelpers.add('insert') } break } @@ -53,21 +56,28 @@ import { template, setAttr, setText, children, on, insert } from 'vue/vapor'\n` for (const [expr, effects] of Object.entries(ir.effect)) { let scope = `watchEffect(() => {\n` + helpers.add('watchEffect') for (const effect of effects) { switch (effect.type) { - case IRNodeTypes.SET_PROP: + case IRNodeTypes.SET_PROP: { scope += `setAttr(n${effect.element}, ${JSON.stringify( effect.name, )}, undefined, ${expr})\n` + vaporHelpers.add('setAttr') break - case IRNodeTypes.SET_TEXT: + } + case IRNodeTypes.SET_TEXT: { scope += `setText(n${effect.element}, undefined, ${expr})\n` + vaporHelpers.add('setText') break - case IRNodeTypes.SET_EVENT: + } + case IRNodeTypes.SET_EVENT: { scope += `on(n${effect.element}, ${JSON.stringify( effect.name, )}, ${expr})\n` + vaporHelpers.add('on') break + } } } scope += '})\n' @@ -76,7 +86,14 @@ import { template, setAttr, setText, children, on, insert } from 'vue/vapor'\n` code += 'return root' + if (vaporHelpers.size) + preamble = + `import { ${[...vaporHelpers].join(', ')} } from 'vue/vapor'\n` + preamble + if (helpers.size) + preamble = `import { ${[...helpers].join(', ')} } from 'vue'\n` + preamble + const functionName = options.ssr ? `ssrRender` : `render` + const isSetupInlined = !!options.inline if (isSetupInlined) { code = `(() => {\n${code}\n})();` } else { @@ -90,7 +107,7 @@ import { template, setAttr, setText, children, on, insert } from 'vue/vapor'\n` } } -function genChildrens(children: DynamicChildren) { +function genChildren(children: DynamicChildren) { let str = '' for (const [index, child] of Object.entries(children)) { str += ` ${index}: [` @@ -98,7 +115,7 @@ function genChildrens(children: DynamicChildren) { str += `n${child.id}` } if (Object.keys(child.children).length) { - str += `, {${genChildrens(child.children)}}` + str += `, {${genChildren(child.children)}}` } str += '],' } diff --git a/packages/compiler-vapor/src/index.ts b/packages/compiler-vapor/src/index.ts index dae557481c..d64408d700 100644 --- a/packages/compiler-vapor/src/index.ts +++ b/packages/compiler-vapor/src/index.ts @@ -2,3 +2,4 @@ export { parse } from '@vue/compiler-dom' export { transform } from './transform' export { generate } from './generate' export { compile } from './compile' +export * from './ir' diff --git a/packages/compiler-vapor/src/ir.ts b/packages/compiler-vapor/src/ir.ts new file mode 100644 index 0000000000..c515797b9d --- /dev/null +++ b/packages/compiler-vapor/src/ir.ts @@ -0,0 +1,72 @@ +import type { SourceLocation } from '@vue/compiler-dom' + +export const enum IRNodeTypes { + ROOT, + TEMPLATE_GENERATOR, + SET_PROP, + SET_TEXT, + SET_EVENT, + + INSERT_NODE, + TEXT_NODE, +} + +export interface IRNode { + type: IRNodeTypes + loc: SourceLocation +} + +export interface RootIRNode extends IRNode { + type: IRNodeTypes.ROOT + template: Array + children: DynamicChildren + effect: Record + opration: OprationNode[] + helpers: Set + vaporHelpers: Set +} + +export interface TemplateGeneratorIRNode extends IRNode { + type: IRNodeTypes.TEMPLATE_GENERATOR + template: string +} + +export interface SetPropIRNode extends IRNode { + type: IRNodeTypes.SET_PROP + element: number + name: string +} + +export interface SetTextIRNode extends IRNode { + type: IRNodeTypes.SET_TEXT + element: number +} + +export interface SetEventIRNode extends IRNode { + type: IRNodeTypes.SET_EVENT + element: number + name: string +} + +export interface TextNodeIRNode extends IRNode { + type: IRNodeTypes.TEXT_NODE + id: number + content: string +} + +export interface InsertNodeIRNode extends IRNode { + type: IRNodeTypes.INSERT_NODE + element: number + parent: number + anchor: number | 'first' | 'last' +} + +export type EffectNode = SetPropIRNode | SetTextIRNode | SetEventIRNode +export type OprationNode = TextNodeIRNode | InsertNodeIRNode + +export interface DynamicChild { + id: number | null + store: boolean + children: DynamicChildren +} +export type DynamicChildren = Record diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index a8c5774570..270ee75883 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -1,85 +1,21 @@ -import { - type NodeTypes, +import type { + NodeTypes, RootNode, Node, TemplateChildNode, ElementNode, AttributeNode, - SourceLocation, InterpolationNode, TransformOptions, DirectiveNode, } from '@vue/compiler-dom' - -export const enum IRNodeTypes { - ROOT, - TEMPLATE_GENERATOR, - SET_PROP, - SET_TEXT, - SET_EVENT, - - INSERT_NODE, - TEXT_NODE, -} - -export interface IRNode { - type: IRNodeTypes - loc: SourceLocation -} - -export interface RootIRNode extends IRNode { - type: IRNodeTypes.ROOT - template: Array - children: DynamicChildren - effect: Record - opration: OprationNode[] - helpers: Set -} - -export interface TemplateGeneratorIRNode extends IRNode { - type: IRNodeTypes.TEMPLATE_GENERATOR - template: string -} - -export interface SetPropIRNode extends IRNode { - type: IRNodeTypes.SET_PROP - element: number - name: string -} - -export interface SetTextIRNode extends IRNode { - type: IRNodeTypes.SET_TEXT - element: number -} - -export interface SetEventIRNode extends IRNode { - type: IRNodeTypes.SET_EVENT - element: number - name: string -} - -export interface TextNodeIRNode extends IRNode { - type: IRNodeTypes.TEXT_NODE - id: number - content: string -} - -export interface InsertNodeIRNode extends IRNode { - type: IRNodeTypes.INSERT_NODE - element: number - parent: number - anchor: number | 'first' | 'last' -} - -export type EffectNode = SetPropIRNode | SetTextIRNode | SetEventIRNode -export type OprationNode = TextNodeIRNode | InsertNodeIRNode - -export interface DynamicChild { - id: number | null - store: boolean - children: DynamicChildren -} -export type DynamicChildren = Record +import { + type DynamicChildren, + type EffectNode, + type OprationNode, + type RootIRNode, + IRNodeTypes, +} from './ir' export interface TransformContext { node: T @@ -87,15 +23,17 @@ export interface TransformContext { root: TransformContext index: number options: TransformOptions - ir: RootIRNode + // ir: RootIRNode template: string children: DynamicChildren store: boolean ghost: boolean getElementId(): number - registerEffect(expr: string, effectNode: EffectNode): void registerTemplate(): number + registerEffect(expr: string, effectNode: EffectNode): void + registerOpration(...oprations: OprationNode[]): void + helper(name: string): string } function createRootContext( @@ -104,7 +42,7 @@ function createRootContext( options: TransformOptions, ): TransformContext { let i = 0 - const { effect: bindings } = ir + const { effect, opration, helpers, vaporHelpers } = ir const ctx: TransformContext = { node, @@ -112,15 +50,14 @@ function createRootContext( index: 0, root: undefined as any, // set later options, - ir, children: {}, store: false, ghost: false, getElementId: () => i++, registerEffect(expr, effectNode) { - if (!bindings[expr]) bindings[expr] = [] - bindings[expr].push(effectNode) + if (!effect[expr]) effect[expr] = [] + effect[expr].push(effectNode) }, template: '', @@ -137,6 +74,14 @@ function createRootContext( }) return ir.template.length - 1 }, + registerOpration(...node) { + opration.push(...node) + }, + // TODO not used yet + helper(name, vapor = true) { + ;(vapor ? vaporHelpers : helpers).add(name) + return name + }, } ctx.root = ctx return ctx @@ -178,12 +123,6 @@ export function transform( root: RootNode, options: TransformOptions = {}, ): RootIRNode { - // { - // type: IRNodeTypes.TEMPLATE_GENERATOR, - // template, - // loc: root.loc - // } - const ir: RootIRNode = { type: IRNodeTypes.ROOT, loc: root.loc, @@ -191,7 +130,8 @@ export function transform( children: {}, effect: Object.create(null), opration: [], - helpers: new Set(['template']), + helpers: new Set([]), + vaporHelpers: new Set([]), } const ctx = createRootContext(ir, root, options) transformChildren(ctx, true) @@ -303,7 +243,7 @@ function transformInterpolation( anchor = isFirst ? 'first' : 'last' } - ctx.ir.opration.push( + ctx.registerOpration( { type: IRNodeTypes.TEXT_NODE, loc: node.loc, @@ -379,6 +319,7 @@ function transformProp( } } +// TODO: reference packages/compiler-core/src/transforms/transformExpression.ts function processExpression(ctx: TransformContext, expr: string) { if (ctx.options.bindingMetadata?.[expr] === 'setup-ref') { expr += '.value'