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 ffa12652c83..1eac397dfa1 100644 --- a/packages/compiler-sfc/__tests__/utils.ts +++ b/packages/compiler-sfc/__tests__/utils.ts @@ -25,7 +25,7 @@ export function assertCode(code: string) { try { babelParse(code, { sourceType: 'module', - plugins: ['typescript'] + plugins: ['typescript', 'jsx'] }) } catch (e: any) { console.log(code) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index cfcc607c72d..58988359068 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -53,6 +53,7 @@ import { 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 { /** @@ -108,6 +109,11 @@ export interface SFCScriptCompileOptions { * @default false */ defineModel?: boolean + /** + * (**Experimental**) Enable macro `defineRender` + * @default false + */ + defineRender?: boolean /** * (**Experimental**) Enable reactive destructure for `defineProps` * @default false @@ -512,7 +518,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)) { @@ -550,7 +557,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 && @@ -832,8 +840,19 @@ export function compileScript( } // 10. generate return statement - let returned - if ( + let returned = '' + if (ctx.renderFunction) { + if (sfc.template) { + warnOnce(`