-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbabelImportDefaultPlugin.js
76 lines (66 loc) · 2.99 KB
/
babelImportDefaultPlugin.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
/**
* A (dirty) babel plugin to transform imports of CJS to ESM compatible default import.
*
* in ESM:
* import ContainerModule from '@mui/material/Container'
*
* out ESM:
* import ContainerModule from '@mui/material/Container'
* const Container = ContainerModule.default
*/
export default function({types: t}) {
return {
visitor: {
// eslint-disable-next-line no-unused-vars
ImportDeclaration(path, state) {
const source = path.node.source.value
// console.log(`Processing import from: ${source}`)
// console.log(`Specifiers: ${JSON.stringify(path.node.specifiers, null, 2)}`)
const isDefaultImport = path.node.specifiers.some(specifier =>
t.isImportDefaultSpecifier(specifier),
)
if(isDefaultImport) {
const originalImportName = path.node.specifiers[0].local.name
// Check if the import already has "Module" suffix to prevent infinite loops
if(originalImportName.endsWith('Module')) {
// console.log(`Skipping transformation for ${originalImportName} to avoid infinite loop.`)
return // Stop further transformation
}
if(isLikelyCommonJS(source, state)) {
console.log(`Transforming ${originalImportName} from CommonJS`)
path.replaceWithMultiple([
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(`${originalImportName}Module`))],
t.stringLiteral(source),
),
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(originalImportName),
t.memberExpression(t.identifier(`${originalImportName}Module`), t.identifier('default')),
),
]),
])
// console.log(`Created new import: ${originalImportName}Module`)
} else {
// console.log(`${source} is likely ESM, no transformation applied.`)
}
}
},
},
}
function isLikelyCommonJS(source, state) {
// Check if the source is from a package with type: module
const isModulePackage = state.file.opts.filename.includes('node_modules') && state.file.opts.packageData
if(isModulePackage && state.file.opts.packageData.type === 'module') {
return false // It's ESM, so return false
}
return (
!source.endsWith('.mjs') &&
(
/node_modules/.test(source)
|| source.startsWith('@mui')
|| source.startsWith('react-helmet')
)
)
}
}