rolldown-plugin-dts 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -17
- package/dist/index.d.ts +37 -4
- package/dist/index.js +205 -93
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/sxzz/rolldown-plugin-dts/actions/workflows/unit-test.yml)
|
|
4
4
|
|
|
5
|
-
A Rolldown plugin to bundle dts files.
|
|
5
|
+
A Rolldown plugin to generate and bundle dts files.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -18,24 +18,59 @@ Add the plugin to your `rolldown.config.js`:
|
|
|
18
18
|
// rolldown.config.js
|
|
19
19
|
import { dts } from 'rolldown-plugin-dts'
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
file: 'dist/index.d.ts',
|
|
28
|
-
format: 'es',
|
|
29
|
-
},
|
|
30
|
-
],
|
|
31
|
-
},
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
export default config
|
|
21
|
+
export default {
|
|
22
|
+
input: './src/index.ts',
|
|
23
|
+
plugins: [dts()],
|
|
24
|
+
output: [{ dir: 'dist', format: 'es' }],
|
|
25
|
+
}
|
|
35
26
|
```
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
You can find a real demo in [here](./rolldown.config.ts).
|
|
29
|
+
|
|
30
|
+
## Options
|
|
31
|
+
|
|
32
|
+
````ts
|
|
33
|
+
interface Options {
|
|
34
|
+
/**
|
|
35
|
+
* When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
|
|
36
|
+
*
|
|
37
|
+
* If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
|
|
38
|
+
*/
|
|
39
|
+
dtsInput?: boolean
|
|
40
|
+
|
|
41
|
+
isolatedDeclaration?: Omit<IsolatedDeclarationsOptions, 'sourcemap'>
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* dts file name alias `{ [filename]: path }`
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* inputAlias: {
|
|
49
|
+
* 'foo.d.ts': 'foo/index.d.ts',
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
inputAlias?: Record<string, string>
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Determines whether the module imported by `.d.ts` files should be treated as external or not.
|
|
56
|
+
*/
|
|
57
|
+
external?: (
|
|
58
|
+
id: string,
|
|
59
|
+
importer: string,
|
|
60
|
+
extraOptions: ResolveIdExtraOptions,
|
|
61
|
+
) => boolean | void
|
|
62
|
+
}
|
|
63
|
+
````
|
|
64
|
+
|
|
65
|
+
## Caveats
|
|
66
|
+
|
|
67
|
+
- The plugin uses Oxc's `isolatedDeclarations` to generate `.d.ts` files,
|
|
68
|
+
which means you need to set `isolatedDeclarations: true` in your `tsconfig.json` and ensure there are no errors.
|
|
69
|
+
|
|
70
|
+
- Namespaces are not supported yet.
|
|
71
|
+
- `export * as ns from './ns'`
|
|
72
|
+
- `import * as ns from './ns'` and then `export { ns }`
|
|
73
|
+
- `type ns = import('./ns')`
|
|
39
74
|
|
|
40
75
|
## Credits
|
|
41
76
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IsolatedDeclarationsOptions } from "oxc-transform";
|
|
2
|
+
import { FunctionPluginHooks, Plugin } from "rolldown";
|
|
2
3
|
|
|
3
|
-
//#region
|
|
4
|
-
declare function
|
|
4
|
+
//#region src/fake-js.d.ts
|
|
5
|
+
declare function createFakeJsPlugin({ dtsInput }: Pick<Options, "dtsInput">): Plugin;
|
|
5
6
|
|
|
6
7
|
//#endregion
|
|
7
|
-
|
|
8
|
+
//#region src/generate.d.ts
|
|
9
|
+
declare function createGeneratePlugin({ isolatedDeclaration, inputAlias, external }: Pick<Options, "external" | "isolatedDeclaration" | "inputAlias">): Plugin;
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/index.d.ts
|
|
13
|
+
type ResolveIdExtraOptions = Parameters<FunctionPluginHooks["resolveId"]>[2];
|
|
14
|
+
interface Options {
|
|
15
|
+
/**
|
|
16
|
+
* When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
|
|
17
|
+
*
|
|
18
|
+
* If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
|
|
19
|
+
*/
|
|
20
|
+
dtsInput?: boolean;
|
|
21
|
+
isolatedDeclaration?: Omit<IsolatedDeclarationsOptions, "sourcemap">;
|
|
22
|
+
/**
|
|
23
|
+
* dts file name alias `{ [filename]: path }`
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* inputAlias: {
|
|
28
|
+
* 'foo.d.ts': 'foo/index.d.ts',
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
inputAlias?: Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* Determines whether the module imported by `.d.ts` files should be treated as external or not.
|
|
34
|
+
*/
|
|
35
|
+
external?: (id: string, importer: string, extraOptions: ResolveIdExtraOptions) => boolean | void;
|
|
36
|
+
}
|
|
37
|
+
declare function dts(options?: Options): Plugin[];
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Options, createFakeJsPlugin, createGeneratePlugin, dts };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { MagicStringAST } from "magic-string-ast";
|
|
3
2
|
import { parseAsync } from "oxc-parser";
|
|
3
|
+
import path, { basename } from "node:path";
|
|
4
|
+
import { isolatedDeclaration } from "oxc-transform";
|
|
4
5
|
|
|
5
6
|
//#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js
|
|
6
7
|
var WalkerBase = class {
|
|
@@ -110,10 +111,10 @@ var SyncWalker = class extends WalkerBase {
|
|
|
110
111
|
if (value && typeof value === "object") {
|
|
111
112
|
if (Array.isArray(value)) {
|
|
112
113
|
const nodes = value;
|
|
113
|
-
for (let i
|
|
114
|
-
const item = nodes[i
|
|
114
|
+
for (let i = 0; i < nodes.length; i += 1) {
|
|
115
|
+
const item = nodes[i];
|
|
115
116
|
if (isNode(item)) {
|
|
116
|
-
if (!this.visit(item, node, key, i
|
|
117
|
+
if (!this.visit(item, node, key, i)) i--;
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
} else if (isNode(value)) this.visit(value, node, key, null);
|
|
@@ -163,25 +164,49 @@ function getIdentifierRange(node, offset = 0) {
|
|
|
163
164
|
return [node.start + offset, node.end + offset];
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/utils/filename.ts
|
|
169
|
+
const RE_JS = /\.([cm]?)js$/;
|
|
170
|
+
const RE_TS = /\.([cm]?)ts$/;
|
|
171
|
+
const RE_DTS = /\.d\.([cm]?)ts$/;
|
|
172
|
+
const RE_NODE_MODULES = /node_modules/;
|
|
173
|
+
function filename_js_to_dts(id) {
|
|
174
|
+
return id.replace(RE_JS, ".d.$1ts");
|
|
175
|
+
}
|
|
176
|
+
function filename_ts_to_dts(id) {
|
|
177
|
+
return id.replace(RE_TS, ".d.$1ts");
|
|
178
|
+
}
|
|
179
|
+
function filename_dts_to(id, ext) {
|
|
180
|
+
return id.replace(RE_DTS, `.$1${ext}`);
|
|
181
|
+
}
|
|
182
|
+
function isRelative(id) {
|
|
183
|
+
return path.isAbsolute(id) || id[0] === ".";
|
|
184
|
+
}
|
|
185
|
+
|
|
166
186
|
//#endregion
|
|
167
187
|
//#region src/utils/magic-string.ts
|
|
168
|
-
function overwriteOrAppend(s, range, replacement) {
|
|
188
|
+
function overwriteOrAppend(s, range, replacement, suffix) {
|
|
169
189
|
if (range[0] === range[1]) {
|
|
170
190
|
s.appendLeft(range[0], ` ${replacement}`);
|
|
171
191
|
return;
|
|
172
192
|
}
|
|
173
|
-
s.
|
|
193
|
+
const original = s.slice(range[0], range[1]);
|
|
194
|
+
if (original !== replacement) s.overwrite(range[0], range[1], replacement + (suffix || ""));
|
|
174
195
|
}
|
|
175
196
|
|
|
176
197
|
//#endregion
|
|
177
|
-
//#region src/
|
|
198
|
+
//#region src/fake-js.ts
|
|
178
199
|
const RE_TYPE = /\btype\b/;
|
|
179
|
-
function
|
|
180
|
-
let
|
|
200
|
+
function createFakeJsPlugin({ dtsInput }) {
|
|
201
|
+
let symbolIdx = 0;
|
|
202
|
+
let identifierIdx = 0;
|
|
181
203
|
const symbolMap = new Map();
|
|
182
|
-
const
|
|
204
|
+
const preserveMap = new Map();
|
|
205
|
+
function getIdentifierIndex() {
|
|
206
|
+
return identifierIdx++;
|
|
207
|
+
}
|
|
183
208
|
function register(info) {
|
|
184
|
-
const symbolId =
|
|
209
|
+
const symbolId = symbolIdx++;
|
|
185
210
|
symbolMap.set(symbolId, info);
|
|
186
211
|
return symbolId;
|
|
187
212
|
}
|
|
@@ -189,8 +214,8 @@ function dts() {
|
|
|
189
214
|
return symbolMap.get(symbolId);
|
|
190
215
|
}
|
|
191
216
|
return {
|
|
192
|
-
name: "rolldown-plugin-dts",
|
|
193
|
-
options(
|
|
217
|
+
name: "rolldown-plugin-dts:fake-js",
|
|
218
|
+
options: dtsInput ? (options) => {
|
|
194
219
|
return {
|
|
195
220
|
...options,
|
|
196
221
|
resolve: {
|
|
@@ -205,85 +230,87 @@ function dts() {
|
|
|
205
230
|
".cjs": [".d.cts"]
|
|
206
231
|
},
|
|
207
232
|
...options.resolve
|
|
208
|
-
},
|
|
209
|
-
onLog(level, log, defaultHandler) {
|
|
210
|
-
if (level === "warn" && log.code === "CIRCULAR_DEPENDENCY") return;
|
|
211
|
-
if (onLog) onLog(level, log, defaultHandler);
|
|
212
|
-
else defaultHandler(level, log);
|
|
213
|
-
},
|
|
214
|
-
treeshake: {
|
|
215
|
-
moduleSideEffects: "no-external",
|
|
216
|
-
unknownGlobalSideEffects: false
|
|
217
233
|
}
|
|
218
234
|
};
|
|
219
|
-
},
|
|
235
|
+
} : void 0,
|
|
220
236
|
outputOptions(options) {
|
|
221
237
|
return {
|
|
222
|
-
|
|
223
|
-
entryFileNames: "[name].ts",
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
resolveId(id, importer) {
|
|
230
|
-
if (importer && !path.isAbsolute(id) && id[0] !== ".") return {
|
|
231
|
-
id,
|
|
232
|
-
external: true
|
|
238
|
+
...options,
|
|
239
|
+
entryFileNames: options.entryFileNames ?? (dtsInput ? "[name].ts" : void 0),
|
|
240
|
+
chunkFileNames(chunk) {
|
|
241
|
+
const original = (typeof options.chunkFileNames === "function" ? options.chunkFileNames(chunk) : options.chunkFileNames) || "[name]-[hash].js";
|
|
242
|
+
if (chunk.name.endsWith(".d")) return filename_js_to_dts(original);
|
|
243
|
+
return original;
|
|
244
|
+
}
|
|
233
245
|
};
|
|
234
246
|
},
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
247
|
+
transform: {
|
|
248
|
+
filter: { id: {
|
|
249
|
+
include: [RE_DTS],
|
|
250
|
+
exclude: [RE_NODE_MODULES]
|
|
251
|
+
} },
|
|
252
|
+
async handler(code, id) {
|
|
253
|
+
const { program, comments } = await parseAsync(id, code);
|
|
254
|
+
const preserved = collectReferenceDirectives(comments);
|
|
255
|
+
preserveMap.set(id, preserved);
|
|
256
|
+
const s = new MagicStringAST(code);
|
|
257
|
+
for (let node of program.body) {
|
|
258
|
+
if (node.type === "ExportAllDeclaration" && node.exported && isRelative(node.source.value)) throw new Error("`export * as foo from './...'` is not supported");
|
|
259
|
+
if (rewriteImportExport(s, node)) continue;
|
|
260
|
+
const sideEffect = node.type === "TSModuleDeclaration" && node.kind !== "namespace";
|
|
261
|
+
const stmt = node;
|
|
262
|
+
const isDefaultExport = node.type === "ExportDefaultDeclaration";
|
|
263
|
+
if ((node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration") && node.declaration) node = node.declaration;
|
|
264
|
+
if (node.type === "VariableDeclaration" && node.declarations.length !== 1) throw new Error("Only one declaration is supported");
|
|
265
|
+
if (node.type === "TSDeclareFunction" || node.type.endsWith("Declaration")) {
|
|
266
|
+
const binding = node.type === "VariableDeclaration" ? node.declarations[0].id : node.id;
|
|
267
|
+
const code$1 = s.sliceNode(node);
|
|
268
|
+
const jsdoc = comments.find((c) => c.type === "Block" && c.value[0] === "*" && c.start < node.start && stmt.start - c.end <= 1);
|
|
269
|
+
const offset = node.start;
|
|
270
|
+
let bindingRange;
|
|
271
|
+
if (sideEffect) bindingRange = [0, 0];
|
|
272
|
+
else if (binding) bindingRange = getIdentifierRange(binding, -offset);
|
|
273
|
+
else if (isDefaultExport) {
|
|
274
|
+
const idx = s.sliceNode(node).indexOf("function") + 8;
|
|
275
|
+
bindingRange = [idx, idx];
|
|
276
|
+
} else continue;
|
|
277
|
+
const depsNodes = collectDependencies(s, node, getIdentifierIndex);
|
|
278
|
+
const depsString = stringifyDependencies(s, depsNodes);
|
|
279
|
+
const depsSymbols = depsNodes.map((dep) => [
|
|
280
|
+
dep.start - offset,
|
|
281
|
+
dep.end - offset,
|
|
282
|
+
dep._suffix
|
|
283
|
+
]);
|
|
284
|
+
const needDeclare = (node.type === "TSEnumDeclaration" || node.type === "ClassDeclaration" || node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction" || node.type === "TSModuleDeclaration" || node.type === "VariableDeclaration") && !node.declare;
|
|
285
|
+
const symbolId = register({
|
|
286
|
+
code: code$1,
|
|
287
|
+
binding: bindingRange,
|
|
288
|
+
deps: depsSymbols,
|
|
289
|
+
needDeclare,
|
|
290
|
+
jsdoc: jsdoc ? s.sliceNode(jsdoc) : void 0,
|
|
291
|
+
preserveName: sideEffect
|
|
292
|
+
});
|
|
293
|
+
const runtime = `[${symbolId}, ${depsString}${depsString && sideEffect ? ", " : ""}${sideEffect ? "sideEffect()" : ""}]`;
|
|
294
|
+
const bindingName = sideEffect ? `_${identifierIdx++}` : binding ? s.sliceNode(binding) : "export_default";
|
|
295
|
+
if (isDefaultExport) s.overwriteNode(stmt, `var ${bindingName} = ${runtime};export { ${bindingName} as default }`);
|
|
296
|
+
else s.overwriteNode(node, `var ${bindingName} = ${runtime};`);
|
|
297
|
+
}
|
|
272
298
|
}
|
|
299
|
+
if (!s.hasChanged()) return;
|
|
300
|
+
const str = s.toString();
|
|
301
|
+
return str;
|
|
273
302
|
}
|
|
274
|
-
if (!s.hasChanged()) return;
|
|
275
|
-
const str = s.toString();
|
|
276
|
-
return str;
|
|
277
303
|
},
|
|
278
304
|
async renderChunk(code, chunk) {
|
|
305
|
+
if (!RE_DTS.test(chunk.fileName)) return;
|
|
279
306
|
const { program } = await parseAsync(chunk.fileName, code);
|
|
280
307
|
const s = new MagicStringAST(code);
|
|
281
308
|
const comments = new Set();
|
|
282
309
|
for (const id of chunk.moduleIds) {
|
|
283
|
-
const preserveComments =
|
|
310
|
+
const preserveComments = preserveMap.get(id);
|
|
284
311
|
if (preserveComments) {
|
|
285
312
|
preserveComments.forEach((c) => comments.add(c));
|
|
286
|
-
|
|
313
|
+
preserveMap.delete(id);
|
|
287
314
|
}
|
|
288
315
|
}
|
|
289
316
|
if (comments.size) s.prepend(`${[...comments].join("\n")}\n`);
|
|
@@ -301,14 +328,14 @@ function dts() {
|
|
|
301
328
|
continue;
|
|
302
329
|
}
|
|
303
330
|
const symbolId = symbolIdNode.value;
|
|
304
|
-
const { code: code$1, binding, deps, needDeclare, jsdoc } = retrieve(symbolId);
|
|
305
|
-
const depsRaw = depsNodes.map((dep) =>
|
|
306
|
-
if (dep.type !== "ArrowFunctionExpression") throw new Error("Expected ArrowFunctionExpression");
|
|
307
|
-
return s.sliceNode(dep.body);
|
|
308
|
-
});
|
|
331
|
+
const { code: code$1, binding, deps, needDeclare, jsdoc, preserveName } = retrieve(symbolId);
|
|
332
|
+
const depsRaw = depsNodes.filter((node$1) => node$1?.type === "ArrowFunctionExpression").map((dep) => s.sliceNode(dep.body));
|
|
309
333
|
const ss = new MagicStringAST(code$1);
|
|
310
|
-
overwriteOrAppend(ss, binding, s.sliceNode(decl.id));
|
|
311
|
-
for (const dep of deps)
|
|
334
|
+
if (!preserveName) overwriteOrAppend(ss, binding, s.sliceNode(decl.id));
|
|
335
|
+
for (const dep of deps) {
|
|
336
|
+
const [start, end, suffix] = dep;
|
|
337
|
+
overwriteOrAppend(ss, [start, end], depsRaw.shift(), suffix);
|
|
338
|
+
}
|
|
312
339
|
if (needDeclare) ss.prepend("declare ");
|
|
313
340
|
if (jsdoc) ss.prepend(`${jsdoc}\n`);
|
|
314
341
|
s.overwriteNode(node, ss.toString());
|
|
@@ -323,10 +350,19 @@ const REFERENCE_RE = /\/\s*<reference\s+(?:path|types)=/;
|
|
|
323
350
|
function collectReferenceDirectives(comment) {
|
|
324
351
|
return comment.filter((c) => REFERENCE_RE.test(c.value)).map((c) => `//${c.value}`);
|
|
325
352
|
}
|
|
326
|
-
function collectDependencies(s, node) {
|
|
353
|
+
function collectDependencies(s, node, getIdentifierIndex) {
|
|
327
354
|
const deps = new Set();
|
|
328
355
|
walk(node, { leave(node$1) {
|
|
329
|
-
if (node$1.type === "
|
|
356
|
+
if (node$1.type === "ExportNamedDeclaration") {
|
|
357
|
+
for (const specifier of node$1.specifiers) if (specifier.type === "ExportSpecifier") {
|
|
358
|
+
let _suffix;
|
|
359
|
+
if (specifier.local.start === specifier.exported.start && specifier.local.end === specifier.exported.end) _suffix = ` as ${s.sliceNode(specifier.local)}`;
|
|
360
|
+
addDependency({
|
|
361
|
+
...specifier.local,
|
|
362
|
+
_suffix
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
} else if (node$1.type === "TSInterfaceDeclaration" && node$1.extends) for (const heritage of node$1.extends || []) addDependency(heritage.expression);
|
|
330
366
|
else if (node$1.type === "ClassDeclaration") {
|
|
331
367
|
if (node$1.superClass) addDependency(node$1.superClass);
|
|
332
368
|
if (node$1.implements) for (const implement of node$1.implements) addDependency(implement.expression);
|
|
@@ -340,7 +376,7 @@ function collectDependencies(s, node) {
|
|
|
340
376
|
if (!node$1.qualifier) throw new Error("Import namespace is not supported");
|
|
341
377
|
const source = node$1.argument.literal.value;
|
|
342
378
|
const imported = s.sliceNode(node$1.qualifier);
|
|
343
|
-
const local = importNamespace(s, source, imported);
|
|
379
|
+
const local = importNamespace(s, source, imported, getIdentifierIndex);
|
|
344
380
|
addDependency({
|
|
345
381
|
type: "Identifier",
|
|
346
382
|
name: local,
|
|
@@ -365,10 +401,9 @@ function patchVariableDeclarator(s, node, decl) {
|
|
|
365
401
|
if (decl.init && !decl.id.typeAnnotation) s.overwriteNode(node, `type ${s.sliceNode(decl.id)} = ${s.sliceNode(decl.init)}`);
|
|
366
402
|
else if (!node.declare) s.prependLeft(node.start, "declare ");
|
|
367
403
|
}
|
|
368
|
-
const RE_D_TS = /\.d\.([cm]?)ts$/;
|
|
369
404
|
function patchImportSource(s, node) {
|
|
370
|
-
if ((node.type === "ImportDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportNamedDeclaration") && node.source?.value &&
|
|
371
|
-
s.overwriteNode(node.source, JSON.stringify(node.source.value
|
|
405
|
+
if ((node.type === "ImportDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportNamedDeclaration") && node.source?.value && RE_DTS.test(node.source.value)) {
|
|
406
|
+
s.overwriteNode(node.source, JSON.stringify(filename_dts_to(node.source.value, "js")));
|
|
372
407
|
return true;
|
|
373
408
|
}
|
|
374
409
|
}
|
|
@@ -393,12 +428,89 @@ function rewriteImportExport(s, node) {
|
|
|
393
428
|
return true;
|
|
394
429
|
}
|
|
395
430
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const local = `_${i++}`;
|
|
431
|
+
function importNamespace(s, source, imported, getIdentifierIndex) {
|
|
432
|
+
const local = `_${getIdentifierIndex()}`;
|
|
399
433
|
s.prepend(`import { ${imported} as ${local} } from ${JSON.stringify(source)};\n`);
|
|
400
434
|
return local;
|
|
401
435
|
}
|
|
402
436
|
|
|
403
437
|
//#endregion
|
|
404
|
-
|
|
438
|
+
//#region src/generate.ts
|
|
439
|
+
function createGeneratePlugin({ isolatedDeclaration: isolatedDeclaration$1, inputAlias, external }) {
|
|
440
|
+
const dtsMap = new Map();
|
|
441
|
+
return {
|
|
442
|
+
name: "rolldown-plugin-dts:generate",
|
|
443
|
+
transform: {
|
|
444
|
+
order: "pre",
|
|
445
|
+
filter: { id: {
|
|
446
|
+
include: [RE_TS],
|
|
447
|
+
exclude: [RE_DTS, RE_NODE_MODULES]
|
|
448
|
+
} },
|
|
449
|
+
handler(code, id) {
|
|
450
|
+
const { code: dtsCode, errors } = isolatedDeclaration(id, code, isolatedDeclaration$1);
|
|
451
|
+
if (errors.length) return this.error(errors[0]);
|
|
452
|
+
const dtsId = filename_ts_to_dts(id);
|
|
453
|
+
dtsMap.set(dtsId, dtsCode);
|
|
454
|
+
const mod = this.getModuleInfo(id);
|
|
455
|
+
if (mod?.isEntry) {
|
|
456
|
+
let fileName = basename(dtsId);
|
|
457
|
+
if (inputAlias?.[fileName]) fileName = inputAlias[fileName];
|
|
458
|
+
this.emitFile({
|
|
459
|
+
type: "chunk",
|
|
460
|
+
id: dtsId,
|
|
461
|
+
fileName
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
async resolveId(id, importer, extraOptions) {
|
|
467
|
+
if (dtsMap.has(id)) return {
|
|
468
|
+
id,
|
|
469
|
+
meta: { dtsFile: true }
|
|
470
|
+
};
|
|
471
|
+
const importerMod = importer ? this.getModuleInfo(importer) : null;
|
|
472
|
+
if (importerMod?.meta.dtsFile) {
|
|
473
|
+
if (!isRelative(id) || external?.(id, importer, extraOptions) === true) return {
|
|
474
|
+
id,
|
|
475
|
+
external: true
|
|
476
|
+
};
|
|
477
|
+
const resolution = await this.resolve(id, filename_dts_to(importer, "ts"));
|
|
478
|
+
if (!resolution || resolution.external) return;
|
|
479
|
+
const dtsId = filename_ts_to_dts(resolution.id);
|
|
480
|
+
if (dtsMap.has(dtsId)) return {
|
|
481
|
+
id: dtsId,
|
|
482
|
+
meta: { dtsFile: true }
|
|
483
|
+
};
|
|
484
|
+
await this.load(resolution);
|
|
485
|
+
if (dtsMap.has(dtsId)) return {
|
|
486
|
+
id: dtsId,
|
|
487
|
+
meta: { dtsFile: true }
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
load: {
|
|
492
|
+
filter: { id: {
|
|
493
|
+
include: [RE_DTS],
|
|
494
|
+
exclude: [RE_NODE_MODULES]
|
|
495
|
+
} },
|
|
496
|
+
handler(id) {
|
|
497
|
+
if (dtsMap.has(id)) return {
|
|
498
|
+
code: dtsMap.get(id),
|
|
499
|
+
moduleSideEffects: false
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
//#endregion
|
|
507
|
+
//#region src/index.ts
|
|
508
|
+
function dts(options = {}) {
|
|
509
|
+
const plugins = [];
|
|
510
|
+
if (!options.dtsInput) plugins.push(createGeneratePlugin(options));
|
|
511
|
+
plugins.push(createFakeJsPlugin(options));
|
|
512
|
+
return plugins;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
//#endregion
|
|
516
|
+
export { createFakeJsPlugin, createGeneratePlugin, dts };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rolldown-plugin-dts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A Rolldown plugin to bundle dts files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,24 +29,25 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"magic-string-ast": "^0.9.1",
|
|
32
|
-
"oxc-parser": "^0.62.0"
|
|
32
|
+
"oxc-parser": "^0.62.0",
|
|
33
|
+
"oxc-transform": "^0.62.0"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@sxzz/eslint-config": "^6.1.1",
|
|
36
37
|
"@sxzz/prettier-config": "^2.2.1",
|
|
37
38
|
"@sxzz/test-utils": "^0.5.4",
|
|
38
39
|
"@types/diff": "^7.0.2",
|
|
39
|
-
"@types/node": "^22.
|
|
40
|
+
"@types/node": "^22.14.0",
|
|
40
41
|
"bumpp": "^10.1.0",
|
|
41
42
|
"diff": "^7.0.0",
|
|
42
|
-
"eslint": "^9.
|
|
43
|
+
"eslint": "^9.24.0",
|
|
43
44
|
"estree-walker": "^3.0.3",
|
|
44
45
|
"prettier": "^3.5.3",
|
|
45
46
|
"rolldown": "1.0.0-beta.7",
|
|
46
47
|
"rollup-plugin-dts": "^6.2.1",
|
|
47
|
-
"tsdown": "^0.
|
|
48
|
+
"tsdown": "^0.8.0-beta.1",
|
|
48
49
|
"tsx": "^4.19.3",
|
|
49
|
-
"typescript": "^5.8.
|
|
50
|
+
"typescript": "^5.8.3",
|
|
50
51
|
"vitest": "^3.1.1"
|
|
51
52
|
},
|
|
52
53
|
"engines": {
|