Skip to content

Commit

Permalink
fix(detect-acorn): identifiers variable not being properly assigned (#…
Browse files Browse the repository at this point in the history
…415)

* fix(detect-acorn): identifiers variable not being properly assigned

* test: add test cases for `matchImports`
  • Loading branch information
Sun79 authored Jan 14, 2025
1 parent f0e69e6 commit d36d8e2
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 7 deletions.
8 changes: 2 additions & 6 deletions src/detect-acorn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export async function detectImportsAcorn(
locations: true,
})

const occurrenceMap = new Map<string, number>()

const virtualImports = createVirtualImportsAcronWalker(map, ctx.options.virtualImports)

const scopes = traveseScopes(
Expand All @@ -39,15 +37,13 @@ export async function detectImportsAcorn(
)

if (enableAutoImport) {
const identifiers = new Set(occurrenceMap.keys())
const identifiers = scopes.unmatched
matchedImports.push(
...Array.from(scopes.unmatched)
...Array.from(identifiers)
.map((name) => {
const item = map.get(name)
if (item && !item.disabled)
return item

occurrenceMap.delete(name)
return null
})
.filter(Boolean) as Import[],
Expand Down
39 changes: 39 additions & 0 deletions test/addon-match-imports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expect, it } from 'vitest'
import { createUnimport } from '../src'
import { resolverAddon } from './share'

describe('addon match imports', () => {
const ctx = createUnimport({
presets: ['vue'],
addons: [
resolverAddon(),
],
})

it('inject', async () => {
const code = `
import otherModule from 'otherModule'
const count = ref(0)
const component1 = ElInput
const component2 = ElSelect
const test = notDefined
console.log(otherModule)
`.trim()

expect((await ctx.injectImports(code)).code)
.toMatchInlineSnapshot(`
"import { ref } from 'vue';
import { ElInput, ElSelect } from 'element-plus/es';
import 'element-plus/es/components/input/style/index';
import 'element-plus/es/components/select/style/index';
import otherModule from 'otherModule'
const count = ref(0)
const component1 = ElInput
const component2 = ElSelect
const test = notDefined
console.log(otherModule)"
`)
})
})
36 changes: 36 additions & 0 deletions test/detect-acorn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { parse } from 'acorn'
import { describe, expect, it } from 'vitest'
import { createUnimport } from '../src'
import { traveseScopes } from '../src/detect-acorn'
import { resolverAddon } from './share'

describe('detect-acorn', () => {
it('scopes', async () => {
Expand Down Expand Up @@ -129,6 +130,41 @@ describe('detect-acorn', () => {
]
`)
})

it('matchedImports', async () => {
const ctx = createUnimport({
parser: 'acorn',
presets: ['vue'],
addons: [
resolverAddon(),
],
})

const code = `
import otherModule from 'otherModule'
const count = ref(0)
const component1 = ElInput
const component2 = ElSelect
const test = notDefined
console.log(otherModule)
`.trim()

expect((await ctx.injectImports(code)).code)
.toMatchInlineSnapshot(`
"import { ref } from 'vue';
import { ElInput, ElSelect } from 'element-plus/es';
import 'element-plus/es/components/input/style/index';
import 'element-plus/es/components/select/style/index';
import otherModule from 'otherModule'
const count = ref(0)
const component1 = ElInput
const component2 = ElSelect
const test = notDefined
console.log(otherModule)"
`)
})
})

describe('virtual imports', () => {
Expand Down
25 changes: 24 additions & 1 deletion test/share.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Addon } from '../src'
import type { Addon, Import } from '../src'
import { kebabCase } from 'scule'

export function functionWrapAddon(): Addon {
return {
Expand Down Expand Up @@ -30,3 +31,25 @@ export function functionWrapAddon(): Addon {
},
}
}

export function resolverAddon(): Addon {
return {
name: 'resolver',
async matchImports(names, matched) {
const dynamic: Import[] = []
for (const name of names) {
if (!name.match(/^El[A-Z]/))
continue
dynamic.push({
name,
from: `element-plus/es`,
}, {
name: 'default',
as: '',
from: `element-plus/es/components/${kebabCase(name.slice(2))}/style/index`,
})
}
return [...matched, ...dynamic]
},
}
}

0 comments on commit d36d8e2

Please sign in to comment.