/
dynamicImportVars.ts
113 lines (99 loc) · 2.81 KB
/
dynamicImportVars.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import MagicString from 'magic-string'
import { init, parse as parseImports } from 'es-module-lexer'
import type { ImportSpecifier } from 'es-module-lexer'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import { transformDynamicImportGlob } from '../importGlob'
import { createFilter } from '@rollup/pluginutils'
export function dynamicImportVars(config: ResolvedConfig): Plugin {
const resolve = config.createResolver({
preferRelative: true,
tryIndex: false,
extensions: []
})
const { include, exclude, warnOnError } =
config.build.dynamicImportVarsOptions
const filter = createFilter(include, exclude)
return {
name: 'vite:dynamic-import-vars',
async transform(source, importer) {
if (
!filter(importer) ||
(importer.includes('node_modules') &&
!source.includes('import.meta.glob'))
) {
return
}
await init
let imports: readonly ImportSpecifier[] = []
try {
imports = parseImports(source)[0]
} catch (e: any) {
this.error(e, e.idx)
}
if (!imports.length) {
return null
}
let s: MagicString | undefined
let importIndex = 0
for (let index = 0; index < imports.length; index++) {
const {
s: start,
e: end,
ss: expStart,
se: expEnd,
d: dynamicIndex
} = imports[index]
if (dynamicIndex === -1 || source[start] !== '`') {
continue
}
s ||= new MagicString(source)
let result
try {
result = await transformDynamicImportGlob(
this,
source,
expStart,
expEnd,
importer,
start,
end,
config.root,
undefined,
resolve
)
} catch (error) {
if (warnOnError) {
this.warn(error)
} else {
this.error(error)
}
}
if (!result) {
continue
}
const { rawPattern, exp } = result
s.prepend(`function __variableDynamicImportRuntime_${importIndex}_(path) {
const glob = ${exp}
return glob[path] ?? new Promise((resolve, reject) => {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}\n`)
s.overwrite(
expStart,
expEnd,
`__variableDynamicImportRuntime_${importIndex}_(\`${rawPattern}\`)`
)
importIndex++
}
if (s) {
return {
code: s.toString(),
map: config.build.sourcemap ? s.generateMap({ hires: true }) : null
}
}
}
}
}