Skip to content

Commit

Permalink
fix(addon): wrong vue directives transform filter (#380)
Browse files Browse the repository at this point in the history
  • Loading branch information
userquin authored Sep 27, 2024
1 parent 478be3f commit cf374a5
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/addons/vue-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,24 @@ export function vueDirectivesAddon(
options: AddonVueDirectivesOptions = {},
): Addon {
function isDirective(importEntry: Import) {
return importEntry.meta?.vueDirective === true
|| (options.isDirective?.(normalizePath(process.cwd(), importEntry.from), importEntry) ?? false)
let isDirective = importEntry.meta?.vueDirective === true
if (isDirective) {
return true
}

isDirective = options.isDirective?.(normalizePath(process.cwd(), importEntry.from), importEntry) ?? false
if (isDirective) {
importEntry.meta ??= {}
importEntry.meta.vueDirective = true
}

return isDirective
}

const self = {
name: VUE_DIRECTIVES_NAME,
async transform(s, id) {
if (!s.original.includes('_ctx.') || !s.original.match(contextRE))
if (!s.original.match(contextRE))
return s

const matches = Array
Expand Down
3 changes: 3 additions & 0 deletions src/presets/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ export const CommonCompositionAPI: InlinePreset['imports'] = [
'Component',
'ComponentPublicInstance',
'ComputedRef',
'DirectiveBinding',
'ExtractDefaultPropTypes',
'ExtractPropTypes',
'ExtractPublicPropTypes',
'InjectionKey',
'PropType',
'Ref',
'MaybeRef',
'MaybeRefOrGetter',
'VNode',
'WritableComputedRef',
].map(name => ({ name, type: true })),
Expand Down
179 changes: 179 additions & 0 deletions test/vue-directives.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ const allDirectives = compileTemplate({
},
})

const onlySingleDirective = compileTemplate({
id: 'template.vue',
filename: 'template.vue',
source: `
<div v-awesome-directive></div>
`,
compilerOptions: {
hoistStatic: false,
},
})

function replaceRoot(code: string) {
return code.replaceAll(process.cwd().replace(/\\/g, '/'), '<root>')
}
Expand Down Expand Up @@ -609,4 +620,172 @@ describe('vue-directives', () => {
`)
})
})

describe('only single directive', async () => {
const ctx = createUnimport({
presets: resolvePresets([{
from: 'directives/awesome-directive.ts',
imports: [{
name: 'AwesomeDirective',
meta: {
vueDirective: true,
},
}],
}]),
addons: {
vueDirectives: true,
},
})

await ctx.init()

it('inject', async () => {
expect(replaceRoot(onlySingleDirective.code)).toMatchInlineSnapshot(`
"import { resolveDirective as _resolveDirective, withDirectives as _withDirectives, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
const _directive_awesome_directive = _resolveDirective("awesome-directive")
return _withDirectives((_openBlock(), _createElementBlock("div", null, null, 512 /* NEED_PATCH */)), [
[_directive_awesome_directive]
])
}"
`)
expect(replaceRoot((await ctx.injectImports(onlySingleDirective.code, 'a.vue')).code.toString())).toMatchInlineSnapshot(`
"import { AwesomeDirective as _directive_awesome_directive } from '<root>/directives/awesome-directive.ts';import { withDirectives as _withDirectives, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
return _withDirectives((_openBlock(), _createElementBlock("div", null, null, 512 /* NEED_PATCH */)), [
[_directive_awesome_directive]
])
}"
`)
})

it('dts', async () => {
expect(replaceRoot(await ctx.generateTypeDeclarations())).toMatchInlineSnapshot(`
"export {}
declare global {
const AwesomeDirective: typeof import('<root>/directives/awesome-directive')['AwesomeDirective']
}
// for vue directives auto import
declare module 'vue' {
interface ComponentCustomProperties {
vAwesomeDirective: typeof import('<root>/directives/awesome-directive')['AwesomeDirective']
}
interface GlobalDirectives {
vAwesomeDirective: typeof import('<root>/directives/awesome-directive')['AwesomeDirective']
}
}"
`)
})
})

describe('directives from scan with meta.vueDirective set to true', async () => {
const cwd = `${process.cwd().replace(/\\/g, '/')}/playground`
const directives = `${cwd}/directives/`
const ctx = createUnimport({
dirsScanOptions: { cwd },
dirs: ['./directives/**'],
addons: {
// DON'T REMOVE: for coverage
addons: [{ declaration: dts => dts }],
// DON'T REMOVE: for coverage
vueTemplate: true,
vueDirectives: {
isDirective(normalizeImportFrom) {
return normalizeImportFrom.includes('/directives/')
},
},
},
})

await ctx.init()

it('meta.vueDirective set to true', async () => {
await ctx.injectImports(allDirectives.code, 'a.vue')
const imports = await ctx.getImports()
.then(imports => imports.filter(i => i.from.startsWith(directives)).map((i) => {
i.from = replaceRoot(i.from)
return i
}))
imports.map(i => expect(i.meta?.vueDirective).toBeTruthy())
expect(imports).toMatchInlineSnapshot(`
[
{
"as": "awesomeDirective",
"from": "<root>/playground/directives/awesome-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "default",
},
{
"as": "AwesomeDirective",
"from": "<root>/playground/directives/awesome-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "AwesomeDirective",
},
{
"as": "customDirective",
"from": "<root>/playground/directives/custom-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "default",
},
{
"as": "CustomDirective",
"from": "<root>/playground/directives/custom-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "CustomDirective",
},
{
"as": "mixedDirective",
"from": "<root>/playground/directives/mixed-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "default",
},
{
"as": "NamedMixedDirective",
"from": "<root>/playground/directives/mixed-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "NamedMixedDirective",
},
{
"as": "NamedDirective",
"from": "<root>/playground/directives/named-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "NamedDirective",
},
{
"as": "vRippleDirective",
"from": "<root>/playground/directives/ripple-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "vRippleDirective",
},
{
"as": "vFocusDirective",
"from": "<root>/playground/directives/v-focus-directive.ts",
"meta": {
"vueDirective": true,
},
"name": "default",
},
]
`)
})
})
})

0 comments on commit cf374a5

Please sign in to comment.