From d046962ab4090aac1ba600c4b6ce67ecb3faf509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Tue, 17 Oct 2023 17:57:58 +0800 Subject: [PATCH 1/8] feat(compiler-sfc): introduce `defineRender` --- .../__snapshots__/defineRender.spec.ts.snap | 47 +++++++++++++++++++ .../compileScript/defineRender.spec.ts | 46 ++++++++++++++++++ packages/compiler-sfc/__tests__/utils.ts | 1 + packages/compiler-sfc/src/compileScript.ts | 27 +++++++++-- packages/compiler-sfc/src/script/context.ts | 4 ++ .../compiler-sfc/src/script/defineRender.ts | 34 ++++++++++++++ 6 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineRender.spec.ts.snap create mode 100644 packages/compiler-sfc/__tests__/compileScript/defineRender.spec.ts create mode 100644 packages/compiler-sfc/src/script/defineRender.ts diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineRender.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineRender.spec.ts.snap new file mode 100644 index 00000000000..8d02ab682e1 --- /dev/null +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineRender.spec.ts.snap @@ -0,0 +1,47 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`defineRender() > JSX Element 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + + +return () =>
+} + +})" +`; + +exports[`defineRender() > function 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + + +return () =>
+} + +})" +`; + +exports[`defineRender() > identifier 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { renderFn } from './ctx' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + + +return renderFn +} + +})" +`; diff --git a/packages/compiler-sfc/__tests__/compileScript/defineRender.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineRender.spec.ts new file mode 100644 index 00000000000..53f3cb3e116 --- /dev/null +++ b/packages/compiler-sfc/__tests__/compileScript/defineRender.spec.ts @@ -0,0 +1,46 @@ +import { compileSFCScript as compile, assertCode } from '../utils' + +describe('defineRender()', () => { + test('JSX Element', () => { + const { content } = compile( + ` + + `, + { defineRender: true } + ) + assertCode(content) + expect(content).toMatch(`return () =>
`) + expect(content).not.toMatch('defineRender') + }) + + test('function', () => { + const { content } = compile( + ` + + `, + { defineRender: true } + ) + assertCode(content) + expect(content).toMatch(`return () =>
`) + expect(content).not.toMatch('defineRender') + }) + + test('identifier', () => { + const { content } = compile( + ` + + `, + { defineRender: true } + ) + assertCode(content) + expect(content).toMatch(`return renderFn`) + expect(content).not.toMatch('defineRender') + }) +}) diff --git a/packages/compiler-sfc/__tests__/utils.ts b/packages/compiler-sfc/__tests__/utils.ts index 5498ede2717..30db906a4ec 100644 --- a/packages/compiler-sfc/__tests__/utils.ts +++ b/packages/compiler-sfc/__tests__/utils.ts @@ -31,6 +31,7 @@ export function assertCode(code: string) { plugins: [ 'typescript', ['importAttributes', { deprecatedAssertSyntax: true }], + 'jsx', ], }) } catch (e: any) { diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 46fc65c0069..851d794f11f 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -55,6 +55,7 @@ import { getImportedName, isCallOf, isLiteralNode } from './script/utils' import { analyzeScriptBindings } from './script/analyzeScriptBindings' import { isImportUsed } from './script/importUsageCheck' import { processAwait } from './script/topLevelAwait' +import { DEFINE_RENDER, processDefineRender } from './script/defineRender' export interface SFCScriptCompileOptions { /** @@ -105,6 +106,11 @@ export interface SFCScriptCompileOptions { * @default true */ hoistStatic?: boolean + /** + * (**Experimental**) Enable macro `defineRender` + * @default false + */ + defineRender?: boolean /** * (**Experimental**) Enable reactive destructure for `defineProps` * @default false @@ -491,7 +497,8 @@ export function compileScript( processDefineProps(ctx, expr) || processDefineEmits(ctx, expr) || processDefineOptions(ctx, expr) || - processDefineSlots(ctx, expr) + processDefineSlots(ctx, expr) || + processDefineRender(ctx, expr) ) { ctx.s.remove(node.start! + startOffset, node.end! + startOffset) } else if (processDefineExpose(ctx, expr)) { @@ -529,7 +536,8 @@ export function compileScript( !isDefineProps && processDefineEmits(ctx, init, decl.id) !isDefineEmits && (processDefineSlots(ctx, init, decl.id) || - processDefineModel(ctx, init, decl.id)) + processDefineModel(ctx, init, decl.id) || + processDefineRender(ctx, init)) if ( isDefineProps && @@ -797,8 +805,19 @@ export function compileScript( } // 9. generate return statement - let returned - if ( + let returned = '' + if (ctx.renderFunction) { + if (sfc.template) { + warnOnce(`