From ff341f54dd1f047724d923ef5f3d4b096d57a424 Mon Sep 17 00:00:00 2001 From: liuseen-l <773890440@qq.com> Date: Wed, 13 Mar 2024 22:56:17 +0800 Subject: [PATCH 1/3] feat: defineDirective --- .../defineDirective.spec.ts.snap | 67 ++++++++++ .../compileScript/defineDirective.spec.ts | 125 ++++++++++++++++++ packages/compiler-sfc/src/compileScript.ts | 4 +- .../src/script/defineDirective.ts | 29 ++++ packages/runtime-core/src/apiSetupHelpers.ts | 11 ++ 5 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineDirective.spec.ts.snap create mode 100644 packages/compiler-sfc/__tests__/compileScript/defineDirective.spec.ts create mode 100644 packages/compiler-sfc/src/script/defineDirective.ts diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineDirective.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineDirective.spec.ts.snap new file mode 100644 index 00000000000..274be42e23d --- /dev/null +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineDirective.spec.ts.snap @@ -0,0 +1,67 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`defineProps > basic usage 2`] = ` +" +export default { + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + +return { vTest } +} + +}" +`; + +exports[`defineProps > use of multiple define micro 2`] = ` +" +export default { + props: { + bar: String + }, + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + const props = __props + const vFoo = { mounted(){} } + +return { vTest, props, vFoo } +} + +}" +`; + +exports[`defineProps > use with other micro 2`] = ` +" +export default { + props: { + bar: String + }, + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + const props = __props + +return { vTest, props } +} + +}" +`; + +exports[`defineProps > with typescript 2`] = ` +"import { defineComponent as _defineComponent } from 'vue' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + +return { vTest } +} + +})" +`; diff --git a/packages/compiler-sfc/__tests__/compileScript/defineDirective.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineDirective.spec.ts new file mode 100644 index 00000000000..54c1331ba0b --- /dev/null +++ b/packages/compiler-sfc/__tests__/compileScript/defineDirective.spec.ts @@ -0,0 +1,125 @@ +import { assertCode, compileSFCScript as compile } from '../utils' + +describe('defineProps', () => { + test('basic usage', () => { + const { content } = compile(` + + `) + expect(content).toMatchInlineSnapshot(` + " + export default { + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + + return { vTest } + } + + }" + `) + + assertCode(content) + expect(content).not.toMatch('defineDirective') + expect(content).toMatch('const vTest = { created(){} }') + expect(content).toMatch('return { vTest }') + }) + + test('with typescript', () => { + const { content } = compile(` + + `) + expect(content).toMatchInlineSnapshot(` + "import { defineComponent as _defineComponent } from 'vue' + + export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + + return { vTest } + } + + })" + `) + + assertCode(content) + expect(content).not.toMatch('defineDirective') + expect(content).toMatch('const vTest = { created(){} }') + expect(content).toMatch('return { vTest }') + }) + + test('use with other micro', () => { + const { content } = compile(` + + `) + expect(content).toMatchInlineSnapshot(` + " + export default { + props: { + bar: String + }, + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + const props = __props + + return { vTest, props } + } + + }" + `) + + assertCode(content) + expect(content).not.toMatch('defineDirective') + expect(content).toMatch('const vTest = { created(){} }') + expect(content).toMatch('return { vTest, props }') + }) + + test('use of multiple define micro', () => { + const { content } = compile(` + + `) + expect(content).toMatchInlineSnapshot(` + " + export default { + props: { + bar: String + }, + setup(__props, { expose: __expose }) { + __expose(); + + const vTest = { created(){} } + const props = __props + const vFoo = { mounted(){} } + + return { vTest, props, vFoo } + } + + }" + `) + + assertCode(content) + expect(content).not.toMatch('defineDirective') + expect(content).toMatch('const vTest = { created(){} }') + expect(content).toMatch('const vFoo = { mounted(){} }') + expect(content).toMatch('return { vTest, props, vFoo }') + }) +}) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index d4131d5c61d..39827a4d757 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 { processDefineDirective } from './script/defineDirective' export interface SFCScriptCompileOptions { /** @@ -529,7 +530,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) || + processDefineDirective(ctx, init, decl.id)) if ( isDefineProps && diff --git a/packages/compiler-sfc/src/script/defineDirective.ts b/packages/compiler-sfc/src/script/defineDirective.ts new file mode 100644 index 00000000000..5044b6d6624 --- /dev/null +++ b/packages/compiler-sfc/src/script/defineDirective.ts @@ -0,0 +1,29 @@ +import type { ScriptCompileContext } from './context' +import type { LVal, Node } from '@babel/types' +import { isCallOf } from './utils' +import { unwrapTSNode } from '@vue/compiler-dom' + +export const DEFINE_DIRECTIVE = 'defineDirective' + +export function processDefineDirective( + ctx: ScriptCompileContext, + node: Node, + declId?: LVal, +) { + if (!isCallOf(node, DEFINE_DIRECTIVE)) { + return false + } + let options: Node | undefined + const arg0 = node.arguments[0] && unwrapTSNode(node.arguments[0]) + options = arg0 + + let optionsString = options && ctx.getString(options) + + ctx.s.overwrite( + ctx.startOffset! + node.start!, + ctx.startOffset! + node.end!, + optionsString, + ) + + return true +} diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index e5f79444da0..0a06d02a950 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -30,6 +30,7 @@ import type { import { warn } from './warning' import type { SlotsType, StrictUnwrapSlotsType } from './componentSlots' import type { Ref } from '@vue/reactivity' +import type { Directive } from './directives' // dev only const warnRuntimeUsage = (method: string) => @@ -479,3 +480,13 @@ export function withAsyncContext(getAwaitable: () => any) { } return [awaitable, () => setCurrentInstance(ctx)] } + +export function defineDirctive( + options: Directive, +): Directive +export function defineDirctive() { + if (__DEV__) { + warnRuntimeUsage('defineDirective') + } + return null as any +} From 23d840cc74f3d5c0e5fc0eeb4e9ffb7211e44ff7 Mon Sep 17 00:00:00 2001 From: liuseen-l <773890440@qq.com> Date: Wed, 13 Mar 2024 22:58:00 +0800 Subject: [PATCH 2/3] feat: comment --- packages/compiler-sfc/src/compileScript.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 39827a4d757..17e899dae92 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -524,7 +524,7 @@ export function compileScript( ) } - // defineProps / defineEmits + // defineProps / defineEmits / defineDirective const isDefineProps = processDefineProps(ctx, init, decl.id) const isDefineEmits = !isDefineProps && processDefineEmits(ctx, init, decl.id) From e05c7f07ab2353b7dce31448ebb96000cb7939ee Mon Sep 17 00:00:00 2001 From: liuseen-l <773890440@qq.com> Date: Wed, 13 Mar 2024 23:01:51 +0800 Subject: [PATCH 3/3] fix: fun called --- packages/runtime-core/src/apiSetupHelpers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 0a06d02a950..e64eeb86fe0 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -481,10 +481,10 @@ export function withAsyncContext(getAwaitable: () => any) { return [awaitable, () => setCurrentInstance(ctx)] } -export function defineDirctive( +export function defineDirective( options: Directive, ): Directive -export function defineDirctive() { +export function defineDirective() { if (__DEV__) { warnRuntimeUsage('defineDirective') }