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