forked from rollup/plugins
/
index.js
102 lines (87 loc) 路 3.14 KB
/
index.js
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
import path from 'path';
import { walk } from 'estree-walker';
import MagicString from 'magic-string';
import fastGlob from 'fast-glob';
import { createFilter } from '@rollup/pluginutils';
import { dynamicImportToGlob, VariableDynamicImportError } from './dynamic-import-to-glob';
function dynamicImportVariables({ include, exclude, warnOnError } = {}) {
const filter = createFilter(include, exclude);
return {
name: 'rollup-plugin-dynamic-import-variables',
transform(code, id) {
if (!filter(id)) {
return null;
}
const parsed = this.parse(code);
let dynamicImportIndex = -1;
let ms;
walk(parsed, {
enter: (node) => {
if (node.type !== 'ImportExpression') {
return;
}
dynamicImportIndex += 1;
try {
// see if this is a variable dynamic import, and generate a glob expression
const glob = dynamicImportToGlob(node.source, code.substring(node.start, node.end));
if (!glob) {
// this was not a variable dynamic import
return;
}
// execute the glob
const result = fastGlob.sync(glob, { cwd: path.dirname(id) });
const paths = result.map((r) =>
r.startsWith('./') || r.startsWith('../') ? r : `./${r}`
);
// create magic string if it wasn't created already
ms = ms || new MagicString(code);
// unpack variable dynamic import into a function with import statements per file, rollup
// will turn these into chunks automatically
ms.prepend(
`function __variableDynamicImportRuntime${dynamicImportIndex}__(path) {
switch (path) {
${paths.map((p) => ` case '${p}': return import('${p}');`).join('\n')}
${` default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})\n`} }
}\n\n`
);
// call the runtime function instead of doing a dynamic import, the import specifier will
// be evaluated at runtime and the correct import will be returned by the injected function
ms.overwrite(
node.start,
node.start + 6,
`__variableDynamicImportRuntime${dynamicImportIndex}__`
);
} catch (error) {
if (error instanceof VariableDynamicImportError) {
// TODO: line number
if (warnOnError) {
this.warn(error);
} else {
this.error(error);
}
} else {
this.error(error);
}
}
}
});
if (ms && dynamicImportIndex !== -1) {
return {
code: ms.toString(),
map: ms.generateMap({
file: id,
includeContent: true,
hires: true
})
};
}
return null;
}
};
}
export default dynamicImportVariables;
export { dynamicImportToGlob, VariableDynamicImportError };