| 1016 | * Credits \@csr632 via #837 |
| 1017 | */ |
| 1018 | export function transformCjsImport( |
| 1019 | importExp: string, |
| 1020 | url: string, |
| 1021 | rawUrl: string, |
| 1022 | importIndex: number, |
| 1023 | importer: string, |
| 1024 | isNodeMode: boolean, |
| 1025 | config: ResolvedConfig, |
| 1026 | ): { importLine: string; hoistedAssignments?: string } | undefined { |
| 1027 | const node = parseAst(importExp).body[0] |
| 1028 | |
| 1029 | // `export * from '...'` may cause unexpected problem, so give it a warning |
| 1030 | if ( |
| 1031 | config.command === 'serve' && |
| 1032 | node.type === 'ExportAllDeclaration' && |
| 1033 | !node.exported |
| 1034 | ) { |
| 1035 | config.logger.warn( |
| 1036 | colors.yellow( |
| 1037 | `\nUnable to interop \`${importExp}\` in ${importer}, this may lose module exports. Please export "${rawUrl}" as ESM or use named exports instead, e.g. \`export { A, B } from "${rawUrl}"\``, |
| 1038 | ), |
| 1039 | ) |
| 1040 | } else if ( |
| 1041 | node.type === 'ImportDeclaration' || |
| 1042 | node.type === 'ExportNamedDeclaration' |
| 1043 | ) { |
| 1044 | if (!node.specifiers.length) { |
| 1045 | return { importLine: `import "${url}"` } |
| 1046 | } |
| 1047 | |
| 1048 | const importNames: ImportNameSpecifier[] = [] |
| 1049 | const exportNames: string[] = [] |
| 1050 | let defaultExports: string = '' |
| 1051 | for (const spec of node.specifiers) { |
| 1052 | if (spec.type === 'ImportSpecifier') { |
| 1053 | const importedName = getIdentifierNameOrLiteralValue(spec.imported) |
| 1054 | const localName = spec.local.name |
| 1055 | importNames.push({ importedName, localName }) |
| 1056 | } else if (spec.type === 'ImportDefaultSpecifier') { |
| 1057 | importNames.push({ |
| 1058 | importedName: 'default', |
| 1059 | localName: spec.local.name, |
| 1060 | }) |
| 1061 | } else if (spec.type === 'ImportNamespaceSpecifier') { |
| 1062 | importNames.push({ importedName: '*', localName: spec.local.name }) |
| 1063 | } else if (spec.type === 'ExportSpecifier') { |
| 1064 | // for ExportSpecifier, local name is same as imported name |
| 1065 | // prefix the variable name to avoid clashing with other local variables |
| 1066 | const importedName = getIdentifierNameOrLiteralValue(spec.local) |
| 1067 | // we want to specify exported name as variable and re-export it |
| 1068 | const exportedName = getIdentifierNameOrLiteralValue(spec.exported) |
| 1069 | if (exportedName === 'default') { |
| 1070 | defaultExports = makeLegalIdentifier( |
| 1071 | `__vite__cjsExportDefault_${importIndex}`, |
| 1072 | ) |
| 1073 | importNames.push({ importedName, localName: defaultExports }) |
| 1074 | } else { |
| 1075 | const localName = `__vite__cjsExport${ |