|
1 | 1 | import path from 'node:path' |
2 | 2 | import { walk } from 'estree-walker' |
3 | | -import { MagicStringAST } from 'magic-string-ast' |
| 3 | +import { MagicStringAST, type MagicString } from 'magic-string-ast' |
4 | 4 | import { |
5 | 5 | parseAsync, |
6 | 6 | type BindingPattern, |
@@ -54,6 +54,18 @@ export function dts(): Plugin { |
54 | 54 | return symbolMap.get(symbolId)! |
55 | 55 | } |
56 | 56 |
|
| 57 | + const importsMap: Record<string, string> = {} |
| 58 | + function importNamespace(s: MagicString, source: string) { |
| 59 | + if (importsMap[source]) return importsMap[source] |
| 60 | + let local = source.replaceAll(/[^a-z0-9]/gi, '_') |
| 61 | + if (/^\d/.test(local[0])) { |
| 62 | + local = `_${local}` |
| 63 | + } |
| 64 | + importsMap[source] = local |
| 65 | + s.prepend(`import * as ${local} from ${JSON.stringify(source)};\n`) |
| 66 | + return local |
| 67 | + } |
| 68 | + |
57 | 69 | return { |
58 | 70 | name: 'rolldown-plugin-dts', |
59 | 71 | options(options) { |
@@ -119,7 +131,7 @@ export function dts(): Plugin { |
119 | 131 | continue |
120 | 132 | } |
121 | 133 |
|
122 | | - const deps = collectDependencies(s, node) |
| 134 | + const deps = collectDependencies(s, node, importNamespace) |
123 | 135 | const depsString = stringifyDependencies(s, deps) |
124 | 136 | const depsRanges: Range[] = deps.map((dep) => [ |
125 | 137 | dep.start - offset, |
@@ -223,11 +235,10 @@ export function dts(): Plugin { |
223 | 235 | } |
224 | 236 | } |
225 | 237 |
|
226 | | -let i = 0 |
227 | | - |
228 | 238 | function collectDependencies( |
229 | 239 | s: MagicStringAST, |
230 | 240 | node: Node, |
| 241 | + importNamespace: (s: MagicString, source: string) => string, |
231 | 242 | ): (Partial<Node> & Span)[] { |
232 | 243 | const deps: Set<Partial<Node> & Span> = new Set() |
233 | 244 |
|
@@ -260,21 +271,20 @@ function collectDependencies( |
260 | 271 | } else if (node.type === 'TSTypeQuery') { |
261 | 272 | addDependency(node.exprName) |
262 | 273 | } else if (node.type === 'TSImportType') { |
263 | | - if (node.argument.type !== 'TSLiteralType') return |
264 | | - const source = s.sliceNode(node.argument) |
265 | | - const local = `_${i++}` |
266 | | - const specifiers = node.qualifier |
267 | | - ? `{ ${s.sliceNode(node.qualifier)} as ${local} }` |
268 | | - : `* as ${local}` |
269 | | - s.prepend(`import ${specifiers} from ${source};\n`) |
270 | | - if (node.qualifier) { |
271 | | - addDependency({ |
272 | | - type: 'Identifier', |
273 | | - name: local, |
274 | | - start: node.start + (node.isTypeOf ? 7 : 0), |
275 | | - end: node.typeArguments ? node.typeArguments.start : node.end, |
276 | | - }) |
277 | | - } |
| 274 | + if ( |
| 275 | + node.argument.type !== 'TSLiteralType' || |
| 276 | + node.argument.literal.type !== 'Literal' || |
| 277 | + typeof node.argument.literal.value !== 'string' |
| 278 | + ) |
| 279 | + return |
| 280 | + const source = node.argument.literal.value |
| 281 | + const local = importNamespace(s, source) |
| 282 | + addDependency({ |
| 283 | + type: 'Identifier', |
| 284 | + name: local, |
| 285 | + start: node.start + (node.isTypeOf ? 7 : 0), |
| 286 | + end: node.argument.end + 1, |
| 287 | + }) |
278 | 288 | } |
279 | 289 | }, |
280 | 290 | }) |
|
0 commit comments