UNPKG

2.96 kBJavaScriptView Raw
1const { extname } = require('path')
2
3/**
4 * @param {Object} babel
5 * @param {import('@babel/types')} babel.types
6 */
7function namedAssetImportPlugin({ types: t }) {
8 const visited = new WeakSet()
9
10 function generateNewSourcePath(loaderMap, moduleName, sourcePath) {
11 const ext = extname(sourcePath).substr(1)
12 const extMap = loaderMap[ext]
13 return extMap[moduleName]
14 ? extMap[moduleName].replace(/\[path\]/, sourcePath)
15 : sourcePath
16 }
17
18 function replaceMatchingSpecifiers(path, loaderMap, callback) {
19 const sourcePath = path.node.source.value
20 const ext = extname(sourcePath).substr(1)
21
22 if (visited.has(path.node) || sourcePath.indexOf('!') !== -1) {
23 return
24 }
25
26 if (loaderMap[ext]) {
27 path.replaceWithMultiple(
28 path.node.specifiers.map(specifier => {
29 const newSpecifier = callback(specifier, sourcePath)
30 visited.add(newSpecifier)
31
32 return newSpecifier
33 })
34 )
35 }
36 }
37
38 return {
39 visitor: {
40 ExportNamedDeclaration(
41 path,
42 {
43 opts: { loaderMap }
44 }
45 ) {
46 if (!path.node.source) {
47 return
48 }
49
50 replaceMatchingSpecifiers(path, loaderMap, (specifier, sourcePath) => {
51 if (t.isExportDefaultSpecifier(specifier)) {
52 return t.exportDeclaration(
53 [t.exportDefaultSpecifier(t.identifier(specifier.local.name))],
54 t.stringLiteral(sourcePath)
55 )
56 }
57
58 const newSourcePath = generateNewSourcePath(
59 loaderMap,
60 specifier.local.name,
61 sourcePath
62 )
63
64 if (newSourcePath === sourcePath) {
65 return t.exportNamedDeclaration(
66 null,
67 [specifier],
68 t.stringLiteral(sourcePath)
69 )
70 }
71
72 return t.exportNamedDeclaration(
73 null,
74 [
75 t.exportSpecifier(
76 t.identifier('default'),
77 t.identifier(specifier.exported.name)
78 )
79 ],
80 t.stringLiteral(newSourcePath)
81 )
82 })
83 },
84 ImportDeclaration(
85 path,
86 {
87 opts: { loaderMap }
88 }
89 ) {
90 replaceMatchingSpecifiers(path, loaderMap, (specifier, sourcePath) => {
91 const isDefaultImport = t.isImportDefaultSpecifier(specifier)
92 const newSoucePath = generateNewSourcePath(
93 loaderMap,
94 isDefaultImport ? 'default' : specifier.imported.name,
95 sourcePath
96 )
97
98 if (newSoucePath === sourcePath) {
99 return t.importDeclaration([specifier], t.stringLiteral(sourcePath))
100 }
101
102 return t.importDeclaration(
103 [t.importDefaultSpecifier(t.identifier(specifier.local.name))],
104 t.stringLiteral(newSoucePath)
105 )
106 })
107 }
108 }
109 }
110}
111
112module.exports = namedAssetImportPlugin