-
-
Notifications
You must be signed in to change notification settings - Fork 334
/
component.ts
67 lines (57 loc) 路 2.23 KB
/
component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import Debug from 'debug'
import type MagicString from 'magic-string'
import { pascalCase, stringifyComponentImport } from '../utils'
import type { Context } from '../context'
import type { ResolveResult } from '../transformer'
import type { SupportedTransformer } from '../..'
const debug = Debug('unplugin-vue-components:transform:component')
const resolveVue2 = (code: string, s: MagicString) => {
const results: ResolveResult[] = []
for (const match of code.matchAll(/(_c|h)\([\s\n\t]*['"](.+?)["']([,)])/g)) {
const [full, renderFunctionName, matchedName, append] = match
if (match.index != null && matchedName && !matchedName.startsWith('_')) {
const start = match.index
const end = start + full.length
results.push({
rawName: matchedName,
replace: resolved => s.overwrite(start, end, `${renderFunctionName}(${resolved}${append}`),
})
}
}
return results
}
const resolveVue3 = (code: string, s: MagicString) => {
const results: ResolveResult[] = []
/**
* when using some plugin like plugin-vue-jsx, resolveComponent will be imported as resolveComponent1 to avoid duplicate import
*/
for (const match of code.matchAll(/_resolveComponent[0-9]*\("(.+?)"\)/g)) {
const matchedName = match[1]
if (match.index != null && matchedName && !matchedName.startsWith('_')) {
const start = match.index
const end = start + match[0].length
results.push({
rawName: matchedName,
replace: resolved => s.overwrite(start, end, resolved),
})
}
}
return results
}
export default async function transformComponent(code: string, transformer: SupportedTransformer, s: MagicString, ctx: Context, sfcPath: string) {
let no = 0
const results = transformer === 'vue2' ? resolveVue2(code, s) : resolveVue3(code, s)
for (const { rawName, replace } of results) {
debug(`| ${rawName}`)
const name = pascalCase(rawName)
ctx.updateUsageMap(sfcPath, [name])
const component = await ctx.findComponent(name, 'component', [sfcPath])
if (component) {
const varName = `__unplugin_components_${no}`
s.prepend(`${stringifyComponentImport({ ...component, as: varName }, ctx)};\n`)
no += 1
replace(varName)
}
}
debug(`^ (${no})`)
}