提交 | 用户 | age
|
77db3d
|
1 |
// 修改自 |
31e271
|
2 |
// https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts |
V |
3 |
|
|
4 |
// TODO 目前还不能监听文件新增及删除 内容已经改变,缓存问题? |
|
5 |
// 可以使用,先不打算集成 |
|
6 |
import { join } from 'path'; |
|
7 |
import { lstatSync } from 'fs'; |
|
8 |
import glob from 'glob'; |
|
9 |
import { createResolver, Resolver } from 'vite/dist/node/resolver.js'; |
|
10 |
import { Transform } from 'vite/dist/node/transform.js'; |
|
11 |
|
|
12 |
const modulesDir: string = join(process.cwd(), '/node_modules/'); |
|
13 |
|
|
14 |
interface SharedConfig { |
|
15 |
root?: string; |
|
16 |
alias?: Record<string, string>; |
|
17 |
resolvers?: Resolver[]; |
|
18 |
} |
|
19 |
|
|
20 |
function template(template: string) { |
|
21 |
return (data: { [x: string]: any }) => { |
|
22 |
return template.replace(/#([^#]+)#/g, (_, g1) => data[g1] || g1); |
|
23 |
}; |
|
24 |
} |
|
25 |
|
|
26 |
const globbyTransform = function (config: SharedConfig): Transform { |
|
27 |
const resolver = createResolver( |
|
28 |
config.root || process.cwd(), |
|
29 |
config.resolvers || [], |
|
30 |
config.alias || {} |
|
31 |
); |
|
32 |
const cache = new Map(); |
|
33 |
|
|
34 |
const urlMap = new Map(); |
|
35 |
return { |
|
36 |
test({ path }) { |
|
37 |
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'? |
|
38 |
try { |
|
39 |
return ( |
|
40 |
!filePath.startsWith(modulesDir) && |
|
41 |
/\.(vue|js|jsx|ts|tsx)$/.test(filePath) && |
|
42 |
lstatSync(filePath).isFile() |
|
43 |
); |
|
44 |
} catch { |
|
45 |
return false; |
|
46 |
} |
|
47 |
}, |
|
48 |
transform({ code, path, isBuild }) { |
|
49 |
let result = cache.get(path); |
|
50 |
if (!result) { |
|
51 |
const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?path)?!([^'"]+)\2/g; |
|
52 |
const match = code.match(reg); |
8a1bfd
|
53 |
if (!match) return code; |
V |
54 |
const lastImport = urlMap.get(path); |
31e271
|
55 |
if (lastImport && match) { |
V |
56 |
code = code.replace(lastImport, match[0]); |
|
57 |
} |
|
58 |
result = code.replace(reg, (_, g1, g2, g3, g4) => { |
|
59 |
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'? |
|
60 |
// resolve path |
|
61 |
const resolvedFilePath = g4.startsWith('.') |
|
62 |
? resolver.resolveRelativeRequest(filePath, g4) |
|
63 |
: { pathname: resolver.requestToFile(g4) }; |
|
64 |
const files = glob.sync(resolvedFilePath.pathname, { dot: true }); |
|
65 |
let templateStr = 'import #name# from #file#'; // import default |
|
66 |
let name = g1; |
|
67 |
const m = g1.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module |
|
68 |
const m2 = g1.match(/\*\s+as\s+(\w+)/); // import * as all module |
|
69 |
if (m) { |
|
70 |
templateStr = `import { ${m[1]} as #name# } from #file#`; |
|
71 |
name = m[3] || m[1]; |
|
72 |
} else if (m2) { |
|
73 |
templateStr = 'import * as #name# from #file#'; |
|
74 |
name = m2[1]; |
|
75 |
} |
|
76 |
const temRender = template(templateStr); |
|
77 |
|
|
78 |
const groups: Array<string>[] = []; |
|
79 |
const replaceFiles = files.map((f, i) => { |
|
80 |
const file = g2 + resolver.fileToRequest(f) + g2; |
|
81 |
groups.push([name + i, file]); |
|
82 |
return temRender({ name: name + i, file }); |
|
83 |
}); |
|
84 |
urlMap.set(path, replaceFiles.join('\n')); |
|
85 |
return ( |
|
86 |
replaceFiles.join('\n') + |
|
87 |
(g3 ? '\n' + groups.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : '') + |
|
88 |
`\nconst ${name} = { ${groups.map((v) => v[0]).join(',')} }\n` |
|
89 |
); |
|
90 |
}); |
|
91 |
if (isBuild) cache.set(path, result); |
|
92 |
} |
|
93 |
return result; |
|
94 |
}, |
|
95 |
}; |
|
96 |
}; |
|
97 |
export default globbyTransform; |