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')
}