Skip to content

Commit 9d9108b

Browse files
authored
fix: directive for vue 2.7 (#487)
1 parent dffdaf9 commit 9d9108b

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

src/core/options.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,16 @@ export function resolveOptions(options: Options, root: string): ResolvedOptions
6565
resolved.types = resolved.types || []
6666

6767
resolved.root = root
68-
resolved.transformer = options.transformer || getVueVersion() || 'vue3'
68+
resolved.transformer = options.transformer || getVueVersion(root) || 'vue3'
6969
resolved.directives = (typeof options.directives === 'boolean')
7070
? options.directives
7171
: !resolved.resolvers.some(i => i.type === 'directive')
7272
? false
73-
: getVueVersion() === 'vue3'
74-
73+
: getVueVersion(root) === 'vue3'
7574
return resolved
7675
}
7776

78-
function getVueVersion() {
79-
const version = getPackageInfoSync('vue')?.version || '3'
77+
function getVueVersion(root: string) {
78+
const version = getPackageInfoSync('vue', { paths: [root] })?.version || '3'
8079
return version.startsWith('2.') ? 'vue2' : 'vue3'
8180
}

src/core/transforms/directive/vue2.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const getRenderFnStart = (ast: ParseResult<File>): number => {
1515
const renderFn = ast.program.body.find((node): node is VariableDeclaration =>
1616
node.type === 'VariableDeclaration'
1717
&& node.declarations[0].id.type === 'Identifier'
18-
&& node.declarations[0].id.name === 'render',
18+
&& ['render', '_sfc_render'].includes(node.declarations[0].id.name),
1919
)
2020
const start = (((renderFn?.declarations[0].init as FunctionExpression)?.body) as BlockStatement)?.start
2121
if (start === null || start === undefined)
@@ -41,7 +41,11 @@ export default async function resolveVue2(code: string, s: MagicString): Promise
4141
},
4242
})
4343

44+
if (nodes.length === 0)
45+
return []
46+
4447
const results: ResolveResult[] = []
48+
const renderStart = getRenderFnStart(ast)
4549
for (const node of nodes) {
4650
const { callee, arguments: args } = node
4751
// _c(_, {})
@@ -58,8 +62,6 @@ export default async function resolveVue2(code: string, s: MagicString): Promise
5862
if (!directives || directives.type !== 'ArrayExpression')
5963
continue
6064

61-
const renderStart = getRenderFnStart(ast)
62-
6365
for (const directive of directives.elements) {
6466
if (directive?.type !== 'ObjectExpression')
6567
continue

test/__snapshots__/transform.test.ts.snap

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@ this.$options.directives[\\"loading\\"] = __unplugin_directives_0;
2323
}
2424
`;
2525

26+
exports[`Component and directive as same name > vue2.7 transform should work 1`] = `
27+
{
28+
"code": "/* unplugin-vue-components disabled */import __unplugin_directives_0 from 'test/directive/Loading';
29+
import __unplugin_components_0 from 'test/component/Div';
30+
31+
import { defineComponent as _defineComponent } from \\"vue\\";
32+
const _sfc_main = /* @__PURE__ */ _defineComponent({
33+
__name: \\"App\\",
34+
setup(__props) {
35+
return { __sfc: true };
36+
}
37+
});
38+
var _sfc_render = function render() {
39+
this.$options.directives[\\"loading\\"] = __unplugin_directives_0;
40+
var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;
41+
return _c(__unplugin_components_0, { directives: [{ name: \\"loading\\", rawName: \\"v-loading\\", value: 123, expression: \\"123\\" }] }, [], 1);
42+
};
43+
",
44+
}
45+
`;
46+
2647
exports[`Component and directive as same name > vue3 transform should work 1`] = `
2748
{
2849
"code": "/* unplugin-vue-components disabled */import __unplugin_directives_0 from 'test/directive/ElInfiniteScroll';

test/transform.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,30 @@ describe('Component and directive as same name', () => {
9191
expect(await ctx.transform(code, '')).toMatchSnapshot()
9292
})
9393

94+
it('vue2.7 transform should work', async () => {
95+
const code = `
96+
import { defineComponent as _defineComponent } from "vue";
97+
const _sfc_main = /* @__PURE__ */ _defineComponent({
98+
__name: "App",
99+
setup(__props) {
100+
return { __sfc: true };
101+
}
102+
});
103+
var _sfc_render = function render() {
104+
var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;
105+
return _c("div", { directives: [{ name: "loading", rawName: "v-loading", value: 123, expression: "123" }] }, [], 1);
106+
};
107+
`
108+
109+
const ctx = new Context({
110+
resolvers: [resolver],
111+
transformer: 'vue2',
112+
directives: true,
113+
})
114+
ctx.sourcemap = false
115+
expect(await ctx.transform(code, '')).toMatchSnapshot()
116+
})
117+
94118
it('vue3 transform should work', async () => {
95119
const code = `
96120
const render = (_ctx, _cache) => {

0 commit comments

Comments
 (0)