rolldown-plugin-dts 0.12.2 → 0.13.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 +43 -16
- package/dist/index.d.ts +49 -24
- package/dist/index.js +74 -180
- package/dist/tsc-CeRgkVKp.js +3 -0
- package/dist/tsc-H_wSbW_C.js +128 -0
- package/dist/utils/tsc-worker.d.ts +27 -0
- package/dist/utils/tsc-worker.js +12 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -32,60 +32,87 @@ You can find an example in [here](./rolldown.config.ts).
|
|
|
32
32
|
## Options
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
|
-
interface Options {
|
|
35
|
+
export interface Options {
|
|
36
36
|
/**
|
|
37
|
-
* The directory
|
|
37
|
+
* The directory in which the plugin will search for the `tsconfig.json` file.
|
|
38
38
|
*/
|
|
39
39
|
cwd?: string
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* Set to `true` if your entry files are `.d.ts` files instead of `.ts` files.
|
|
43
43
|
*
|
|
44
|
-
*
|
|
44
|
+
* When enabled, the plugin will skip generating a `.d.ts` file for the entry point.
|
|
45
45
|
*/
|
|
46
46
|
dtsInput?: boolean
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* If `true`, the plugin will emit only `.d.ts` files and remove all other output chunks.
|
|
50
50
|
*
|
|
51
|
-
* This
|
|
51
|
+
* This is especially useful when generating `.d.ts` files for the CommonJS format as part of a separate build step.
|
|
52
52
|
*/
|
|
53
53
|
emitDtsOnly?: boolean
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* The path to the `tsconfig.json` file.
|
|
57
57
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
58
|
+
* If set to `false`, the plugin will ignore any `tsconfig.json` file.
|
|
59
|
+
* You can still specify `compilerOptions` directly in the options.
|
|
60
60
|
*
|
|
61
|
-
* @default
|
|
61
|
+
* @default 'tsconfig.json'
|
|
62
62
|
*/
|
|
63
63
|
tsconfig?: string | boolean
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
66
|
+
* Pass a raw `tsconfig.json` object directly to the plugin.
|
|
67
67
|
*
|
|
68
|
-
* @see https://www.typescriptlang.org/
|
|
68
|
+
* @see https://www.typescriptlang.org/tsconfig
|
|
69
|
+
*/
|
|
70
|
+
tsconfigRaw?: Omit<TsConfigJson, 'compilerOptions'>
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Override the `compilerOptions` specified in `tsconfig.json`.
|
|
74
|
+
*
|
|
75
|
+
* @see https://www.typescriptlang.org/tsconfig/#compilerOptions
|
|
69
76
|
*/
|
|
70
77
|
compilerOptions?: TsConfigJson.CompilerOptions
|
|
71
78
|
|
|
72
79
|
/**
|
|
73
|
-
*
|
|
74
|
-
* which is
|
|
80
|
+
* If `true`, the plugin will generate `.d.ts` files using Oxc,
|
|
81
|
+
* which is significantly faster than the TypeScript compiler.
|
|
75
82
|
*
|
|
76
|
-
* This option is enabled when `isolatedDeclarations` in `compilerOptions` is set to `true`.
|
|
83
|
+
* This option is automatically enabled when `isolatedDeclarations` in `compilerOptions` is set to `true`.
|
|
77
84
|
*/
|
|
78
85
|
isolatedDeclarations?:
|
|
79
86
|
| boolean
|
|
80
87
|
| Omit<IsolatedDeclarationsOptions, 'sourcemap'>
|
|
81
88
|
|
|
82
89
|
/**
|
|
83
|
-
*
|
|
90
|
+
* If `true`, the plugin will generate declaration maps (`.d.ts.map`) for `.d.ts` files.
|
|
84
91
|
*/
|
|
85
92
|
sourcemap?: boolean
|
|
86
93
|
|
|
87
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Resolve external types used in `.d.ts` files from `node_modules`.
|
|
96
|
+
*/
|
|
88
97
|
resolve?: boolean | (string | RegExp)[]
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* If `true`, the plugin will generate `.d.ts` files using `vue-tsc`.
|
|
101
|
+
*/
|
|
102
|
+
vue?: boolean
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* If `true`, the plugin will launch a separate process for `tsc` or `vue-tsc`.
|
|
106
|
+
* This enables processing multiple projects in parallel.
|
|
107
|
+
*/
|
|
108
|
+
parallel?: boolean
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* If `true`, the plugin will prepare all files listed in `tsconfig.json` for `tsc` or `vue-tsc`.
|
|
112
|
+
*
|
|
113
|
+
* This is especially useful when you have a single `tsconfig.json` for multiple projects in a monorepo.
|
|
114
|
+
*/
|
|
115
|
+
eager?: boolean
|
|
89
116
|
}
|
|
90
117
|
```
|
|
91
118
|
|
package/dist/index.d.ts
CHANGED
|
@@ -11,81 +11,106 @@ declare function createFakeJsPlugin({
|
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region src/generate.d.ts
|
|
13
13
|
declare function createGeneratePlugin({
|
|
14
|
-
|
|
14
|
+
tsconfigRaw,
|
|
15
|
+
tsconfigDir,
|
|
15
16
|
isolatedDeclarations,
|
|
16
17
|
emitDtsOnly,
|
|
17
|
-
vue
|
|
18
|
-
|
|
18
|
+
vue,
|
|
19
|
+
parallel,
|
|
20
|
+
eager
|
|
21
|
+
}: Pick<OptionsResolved, "tsconfigRaw" | "tsconfigDir" | "isolatedDeclarations" | "emitDtsOnly" | "vue" | "parallel" | "eager">): Plugin;
|
|
19
22
|
|
|
20
23
|
//#endregion
|
|
21
24
|
//#region src/index.d.ts
|
|
22
25
|
interface Options {
|
|
23
26
|
/**
|
|
24
|
-
* The directory
|
|
27
|
+
* The directory in which the plugin will search for the `tsconfig.json` file.
|
|
25
28
|
*/
|
|
26
29
|
cwd?: string;
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* Set to `true` if your entry files are `.d.ts` files instead of `.ts` files.
|
|
29
32
|
*
|
|
30
|
-
*
|
|
33
|
+
* When enabled, the plugin will skip generating a `.d.ts` file for the entry point.
|
|
31
34
|
*/
|
|
32
35
|
dtsInput?: boolean;
|
|
33
36
|
/**
|
|
34
|
-
*
|
|
37
|
+
* If `true`, the plugin will emit only `.d.ts` files and remove all other output chunks.
|
|
35
38
|
*
|
|
36
|
-
* This
|
|
39
|
+
* This is especially useful when generating `.d.ts` files for the CommonJS format as part of a separate build step.
|
|
37
40
|
*/
|
|
38
41
|
emitDtsOnly?: boolean;
|
|
39
42
|
/**
|
|
40
43
|
* The path to the `tsconfig.json` file.
|
|
41
44
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
45
|
+
* If set to `false`, the plugin will ignore any `tsconfig.json` file.
|
|
46
|
+
* You can still specify `compilerOptions` directly in the options.
|
|
44
47
|
*
|
|
45
|
-
* @default
|
|
48
|
+
* @default 'tsconfig.json'
|
|
46
49
|
*/
|
|
47
50
|
tsconfig?: string | boolean;
|
|
48
51
|
/**
|
|
49
|
-
*
|
|
52
|
+
* Pass a raw `tsconfig.json` object directly to the plugin.
|
|
53
|
+
*
|
|
54
|
+
* @see https://www.typescriptlang.org/tsconfig
|
|
55
|
+
*/
|
|
56
|
+
tsconfigRaw?: Omit<TsConfigJson, "compilerOptions">;
|
|
57
|
+
/**
|
|
58
|
+
* Override the `compilerOptions` specified in `tsconfig.json`.
|
|
50
59
|
*
|
|
51
|
-
* @see https://www.typescriptlang.org/
|
|
60
|
+
* @see https://www.typescriptlang.org/tsconfig/#compilerOptions
|
|
52
61
|
*/
|
|
53
62
|
compilerOptions?: TsConfigJson.CompilerOptions;
|
|
54
63
|
/**
|
|
55
|
-
*
|
|
56
|
-
* which is
|
|
64
|
+
* If `true`, the plugin will generate `.d.ts` files using Oxc,
|
|
65
|
+
* which is significantly faster than the TypeScript compiler.
|
|
57
66
|
*
|
|
58
|
-
* This option is enabled when `isolatedDeclarations` in `compilerOptions` is set to `true`.
|
|
67
|
+
* This option is automatically enabled when `isolatedDeclarations` in `compilerOptions` is set to `true`.
|
|
59
68
|
*/
|
|
60
69
|
isolatedDeclarations?: boolean | Omit<IsolatedDeclarationsOptions, "sourcemap">;
|
|
61
70
|
/**
|
|
62
|
-
*
|
|
71
|
+
* If `true`, the plugin will generate declaration maps (`.d.ts.map`) for `.d.ts` files.
|
|
63
72
|
*/
|
|
64
73
|
sourcemap?: boolean;
|
|
65
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Resolve external types used in `.d.ts` files from `node_modules`.
|
|
76
|
+
*/
|
|
66
77
|
resolve?: boolean | (string | RegExp)[];
|
|
67
78
|
/**
|
|
68
|
-
*
|
|
79
|
+
* If `true`, the plugin will generate `.d.ts` files using `vue-tsc`.
|
|
69
80
|
*/
|
|
70
81
|
vue?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* If `true`, the plugin will launch a separate process for `tsc` or `vue-tsc`.
|
|
84
|
+
* This enables processing multiple projects in parallel.
|
|
85
|
+
*/
|
|
86
|
+
parallel?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* If `true`, the plugin will prepare all files listed in `tsconfig.json` for `tsc` or `vue-tsc`.
|
|
89
|
+
*
|
|
90
|
+
* This is especially useful when you have a single `tsconfig.json` for multiple projects in a monorepo.
|
|
91
|
+
*/
|
|
92
|
+
eager?: boolean;
|
|
71
93
|
}
|
|
72
94
|
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
|
73
|
-
type OptionsResolved = Overwrite<Required<Options
|
|
95
|
+
type OptionsResolved = Overwrite<Required<Omit<Options, "compilerOptions">>, {
|
|
74
96
|
tsconfig: string | undefined;
|
|
75
97
|
isolatedDeclarations: IsolatedDeclarationsOptions | false;
|
|
98
|
+
tsconfigRaw: TsConfigJson;
|
|
99
|
+
tsconfigDir: string;
|
|
76
100
|
}>;
|
|
77
101
|
declare function dts(options?: Options): Plugin[];
|
|
78
102
|
declare function resolveOptions({
|
|
79
103
|
cwd,
|
|
80
104
|
tsconfig,
|
|
81
105
|
compilerOptions,
|
|
106
|
+
tsconfigRaw: overriddenTsconfigRaw,
|
|
82
107
|
isolatedDeclarations,
|
|
83
108
|
sourcemap,
|
|
84
109
|
dtsInput,
|
|
85
110
|
emitDtsOnly,
|
|
86
111
|
resolve,
|
|
87
|
-
vue
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
//#endregion
|
|
112
|
+
vue,
|
|
113
|
+
parallel,
|
|
114
|
+
eager
|
|
115
|
+
}: Options): OptionsResolved; //#endregion
|
|
91
116
|
export { Options, OptionsResolved, createFakeJsPlugin, createGeneratePlugin, dts, resolveOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import process from "node:process";
|
|
4
3
|
import Debug from "debug";
|
|
@@ -7,6 +6,8 @@ import _generate from "@babel/generator";
|
|
|
7
6
|
import { parse } from "@babel/parser";
|
|
8
7
|
import * as t from "@babel/types";
|
|
9
8
|
import { isDeclarationType, isTypeOf } from "ast-kit";
|
|
9
|
+
import { fork } from "node:child_process";
|
|
10
|
+
import { createBirpc } from "birpc";
|
|
10
11
|
import { ResolverFactory, isolatedDeclaration } from "rolldown/experimental";
|
|
11
12
|
import { createResolver } from "dts-resolver";
|
|
12
13
|
|
|
@@ -297,7 +298,6 @@ function createFakeJsPlugin({ dtsInput, sourcemap }) {
|
|
|
297
298
|
const isDecl = isTypeOf(stmt, ["ExportNamedDeclaration", "ExportDefaultDeclaration"]) && stmt.declaration;
|
|
298
299
|
const decl = isDecl ? stmt.declaration : stmt;
|
|
299
300
|
const setDecl = isDecl ? (node) => stmt.declaration = node : setStmt;
|
|
300
|
-
if (decl.type === "VariableDeclaration" && decl.declarations.length !== 1) throw new Error("Only one declaration is supported");
|
|
301
301
|
if (decl.type !== "TSDeclareFunction" && !isDeclarationType(decl)) continue;
|
|
302
302
|
if (isTypeOf(decl, [
|
|
303
303
|
"TSEnumDeclaration",
|
|
@@ -307,12 +307,17 @@ function createFakeJsPlugin({ dtsInput, sourcemap }) {
|
|
|
307
307
|
"TSModuleDeclaration",
|
|
308
308
|
"VariableDeclaration"
|
|
309
309
|
])) decl.declare = true;
|
|
310
|
-
|
|
311
|
-
if (
|
|
312
|
-
|
|
310
|
+
const bindings = [];
|
|
311
|
+
if (decl.type === "VariableDeclaration") bindings.push(...decl.declarations.map((decl$1) => decl$1.id));
|
|
312
|
+
else if ("id" in decl && decl.id) {
|
|
313
|
+
let binding = decl.id;
|
|
314
|
+
binding = sideEffect ? t.identifier(`_${identifierIdx++}`) : binding;
|
|
315
|
+
bindings.push(binding);
|
|
316
|
+
} else {
|
|
317
|
+
const binding = t.identifier("export_default");
|
|
318
|
+
bindings.push(binding);
|
|
313
319
|
decl.id = binding;
|
|
314
320
|
}
|
|
315
|
-
binding = sideEffect ? t.identifier(`_${identifierIdx++}`) : binding;
|
|
316
321
|
const deps = collectDependencies(decl, namespaceStmts);
|
|
317
322
|
const elements = [
|
|
318
323
|
t.numericLiteral(0),
|
|
@@ -328,7 +333,7 @@ function createFakeJsPlugin({ dtsInput, sourcemap }) {
|
|
|
328
333
|
const symbolId = registerSymbol({
|
|
329
334
|
decl,
|
|
330
335
|
deps,
|
|
331
|
-
|
|
336
|
+
bindings
|
|
332
337
|
});
|
|
333
338
|
elements[0] = t.numericLiteral(symbolId);
|
|
334
339
|
const runtimeAssignment = {
|
|
@@ -337,14 +342,20 @@ function createFakeJsPlugin({ dtsInput, sourcemap }) {
|
|
|
337
342
|
declarations: [{
|
|
338
343
|
type: "VariableDeclarator",
|
|
339
344
|
id: {
|
|
340
|
-
...
|
|
345
|
+
...bindings[0],
|
|
341
346
|
typeAnnotation: null
|
|
342
347
|
},
|
|
343
348
|
init: runtime
|
|
344
|
-
}
|
|
349
|
+
}, ...bindings.slice(1).map((binding) => ({
|
|
350
|
+
type: "VariableDeclarator",
|
|
351
|
+
id: {
|
|
352
|
+
...binding,
|
|
353
|
+
typeAnnotation: null
|
|
354
|
+
}
|
|
355
|
+
}))]
|
|
345
356
|
};
|
|
346
357
|
if (isDefaultExport) {
|
|
347
|
-
appendStmts.push(t.exportNamedDeclaration(null, [t.exportSpecifier(
|
|
358
|
+
appendStmts.push(t.exportNamedDeclaration(null, [t.exportSpecifier(bindings[0], t.identifier("default"))]));
|
|
348
359
|
setStmt(runtimeAssignment);
|
|
349
360
|
} else setDecl(runtimeAssignment);
|
|
350
361
|
}
|
|
@@ -367,18 +378,20 @@ function createFakeJsPlugin({ dtsInput, sourcemap }) {
|
|
|
367
378
|
program.body = patchTsNamespace(program.body);
|
|
368
379
|
program.body = program.body.map((node) => {
|
|
369
380
|
if (patchImportSource(node)) return node;
|
|
370
|
-
if (node.type !== "VariableDeclaration"
|
|
381
|
+
if (node.type !== "VariableDeclaration") return node;
|
|
371
382
|
const [decl] = node.declarations;
|
|
372
383
|
if (decl.init?.type !== "ArrayExpression" || !decl.init.elements[0]) return null;
|
|
373
384
|
const [symbolIdNode, ...depsFns] = decl.init.elements;
|
|
374
385
|
if (symbolIdNode?.type !== "NumericLiteral") return null;
|
|
375
386
|
const symbolId = symbolIdNode.value;
|
|
376
387
|
const original = getSymbol(symbolId);
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
388
|
+
for (const [i, decl$1] of node.declarations.entries()) {
|
|
389
|
+
const transformedBinding = {
|
|
390
|
+
...decl$1.id,
|
|
391
|
+
typeAnnotation: original.bindings[i].typeAnnotation
|
|
392
|
+
};
|
|
393
|
+
overwriteNode(original.bindings[i], transformedBinding);
|
|
394
|
+
}
|
|
382
395
|
const transformedDeps = depsFns.filter((node$1) => node$1?.type === "ArrowFunctionExpression").map((node$1) => node$1.body);
|
|
383
396
|
if (original.deps.length) for (let i = 0; i < original.deps.length; i++) {
|
|
384
397
|
const originalDep = original.deps[i];
|
|
@@ -616,153 +629,11 @@ function inheritNodeComments(oldNode, newNode) {
|
|
|
616
629
|
}
|
|
617
630
|
}
|
|
618
631
|
|
|
619
|
-
//#endregion
|
|
620
|
-
//#region src/utils/vue.ts
|
|
621
|
-
const debug$3 = Debug("rolldown-plugin-dts:vue");
|
|
622
|
-
let createVueProgram;
|
|
623
|
-
const require = createRequire(import.meta.url);
|
|
624
|
-
function loadVueLanguageTools() {
|
|
625
|
-
try {
|
|
626
|
-
const vueTscPath = require.resolve("vue-tsc");
|
|
627
|
-
const { proxyCreateProgram } = require(require.resolve("@volar/typescript", { paths: [vueTscPath] }));
|
|
628
|
-
const vue = require(require.resolve("@vue/language-core", { paths: [vueTscPath] }));
|
|
629
|
-
return {
|
|
630
|
-
proxyCreateProgram,
|
|
631
|
-
vue
|
|
632
|
-
};
|
|
633
|
-
} catch (error) {
|
|
634
|
-
debug$3("vue language tools not found", error);
|
|
635
|
-
throw new Error("Failed to load vue language tools. Please manually install vue-tsc.");
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
function createVueProgramFactory() {
|
|
639
|
-
if (createVueProgram) return createVueProgram;
|
|
640
|
-
debug$3("loading vue language tools");
|
|
641
|
-
const { proxyCreateProgram, vue } = loadVueLanguageTools();
|
|
642
|
-
return createVueProgram = proxyCreateProgram(ts, ts.createProgram, (ts$1, options) => {
|
|
643
|
-
const { configFilePath } = options.options;
|
|
644
|
-
const vueOptions = typeof configFilePath === "string" ? vue.createParsedCommandLine(ts$1, ts$1.sys, configFilePath.replaceAll("\\", "/")).vueOptions : vue.getDefaultCompilerOptions();
|
|
645
|
-
const vueLanguagePlugin = vue.createVueLanguagePlugin(ts$1, options.options, vueOptions, (id) => id);
|
|
646
|
-
return { languagePlugins: [vueLanguagePlugin] };
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
//#endregion
|
|
651
|
-
//#region src/utils/tsc.ts
|
|
652
|
-
const debug$2 = Debug("rolldown-plugin-dts:tsc");
|
|
653
|
-
let ts;
|
|
654
|
-
let formatHost;
|
|
655
|
-
function initTs() {
|
|
656
|
-
debug$2("loading typescript");
|
|
657
|
-
const require$1 = createRequire(import.meta.url);
|
|
658
|
-
ts = require$1("typescript");
|
|
659
|
-
formatHost = {
|
|
660
|
-
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
|
|
661
|
-
getNewLine: () => ts.sys.newLine,
|
|
662
|
-
getCanonicalFileName: ts.sys.useCaseSensitiveFileNames ? (f) => f : (f) => f.toLowerCase()
|
|
663
|
-
};
|
|
664
|
-
debug$2(`loaded typescript: ${ts.version}`);
|
|
665
|
-
}
|
|
666
|
-
const defaultCompilerOptions = {
|
|
667
|
-
declaration: true,
|
|
668
|
-
noEmit: false,
|
|
669
|
-
emitDeclarationOnly: true,
|
|
670
|
-
noEmitOnError: true,
|
|
671
|
-
checkJs: false,
|
|
672
|
-
declarationMap: false,
|
|
673
|
-
skipLibCheck: true,
|
|
674
|
-
target: 99,
|
|
675
|
-
resolveJsonModule: true
|
|
676
|
-
};
|
|
677
|
-
function createOrGetTsModule(programs, compilerOptions, id, isEntry, dtsMap, vue) {
|
|
678
|
-
const program = programs.find((program$1) => {
|
|
679
|
-
if (isEntry) return program$1.getRootFileNames().includes(id);
|
|
680
|
-
return program$1.getSourceFile(id);
|
|
681
|
-
});
|
|
682
|
-
if (program) {
|
|
683
|
-
const sourceFile = program.getSourceFile(id);
|
|
684
|
-
if (sourceFile) return {
|
|
685
|
-
program,
|
|
686
|
-
file: sourceFile
|
|
687
|
-
};
|
|
688
|
-
}
|
|
689
|
-
debug$2(`create program for module: ${id}`);
|
|
690
|
-
const module = createTsProgram(compilerOptions, dtsMap, id, vue);
|
|
691
|
-
debug$2(`created program for module: ${id}`);
|
|
692
|
-
programs.push(module.program);
|
|
693
|
-
return module;
|
|
694
|
-
}
|
|
695
|
-
function createTsProgram(compilerOptions, dtsMap, id, vue) {
|
|
696
|
-
const overrideCompilerOptions = ts.convertCompilerOptionsFromJson(compilerOptions, ".").options;
|
|
697
|
-
const options = {
|
|
698
|
-
...defaultCompilerOptions,
|
|
699
|
-
...overrideCompilerOptions
|
|
700
|
-
};
|
|
701
|
-
const host = ts.createCompilerHost(options, true);
|
|
702
|
-
const { readFile: _readFile, fileExists: _fileExists } = host;
|
|
703
|
-
host.fileExists = (fileName) => {
|
|
704
|
-
const module = getTsModule(dtsMap, fileName);
|
|
705
|
-
if (module) return true;
|
|
706
|
-
if (debug$2.enabled && !RE_NODE_MODULES.test(fileName)) debug$2(`file exists from fs: ${fileName}`);
|
|
707
|
-
return _fileExists(fileName);
|
|
708
|
-
};
|
|
709
|
-
host.readFile = (fileName) => {
|
|
710
|
-
const module = getTsModule(dtsMap, fileName);
|
|
711
|
-
if (module) return module.code;
|
|
712
|
-
if (debug$2.enabled && !RE_NODE_MODULES.test(fileName)) debug$2(`read file from fs: ${fileName}`);
|
|
713
|
-
return _readFile(fileName);
|
|
714
|
-
};
|
|
715
|
-
const entries = [...new Set([...Array.from(dtsMap.values()).filter((v) => v.isEntry).map((v) => v.id), id])];
|
|
716
|
-
const createProgram = vue ? createVueProgramFactory() : ts.createProgram;
|
|
717
|
-
const program = createProgram({
|
|
718
|
-
rootNames: entries,
|
|
719
|
-
options,
|
|
720
|
-
host
|
|
721
|
-
});
|
|
722
|
-
const sourceFile = program.getSourceFile(id);
|
|
723
|
-
if (!sourceFile) throw new Error(`Source file not found: ${id}`);
|
|
724
|
-
return {
|
|
725
|
-
program,
|
|
726
|
-
file: sourceFile
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
function tscEmit(module) {
|
|
730
|
-
const { program, file } = module;
|
|
731
|
-
let dtsCode;
|
|
732
|
-
let map;
|
|
733
|
-
const { emitSkipped, diagnostics } = program.emit(
|
|
734
|
-
file,
|
|
735
|
-
(fileName, code) => {
|
|
736
|
-
if (fileName.endsWith(".map")) {
|
|
737
|
-
debug$2(`emit dts sourcemap: ${fileName}`);
|
|
738
|
-
map = JSON.parse(code);
|
|
739
|
-
} else {
|
|
740
|
-
debug$2(`emit dts: ${fileName}`);
|
|
741
|
-
dtsCode = code;
|
|
742
|
-
}
|
|
743
|
-
},
|
|
744
|
-
void 0,
|
|
745
|
-
true,
|
|
746
|
-
void 0,
|
|
747
|
-
// @ts-expect-error private API: forceDtsEmit
|
|
748
|
-
true
|
|
749
|
-
);
|
|
750
|
-
if (emitSkipped && diagnostics.length) return { error: ts.formatDiagnostics(diagnostics, formatHost) };
|
|
751
|
-
return {
|
|
752
|
-
code: dtsCode,
|
|
753
|
-
map
|
|
754
|
-
};
|
|
755
|
-
}
|
|
756
|
-
function getTsModule(dtsMap, tsId) {
|
|
757
|
-
const module = Array.from(dtsMap.values()).find((dts$1) => dts$1.id === tsId);
|
|
758
|
-
if (!module) return;
|
|
759
|
-
return module;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
632
|
//#endregion
|
|
763
633
|
//#region src/generate.ts
|
|
764
634
|
const debug$1 = Debug("rolldown-plugin-dts:generate");
|
|
765
|
-
|
|
635
|
+
const WORKER_URL = "./utils/tsc-worker.js";
|
|
636
|
+
function createGeneratePlugin({ tsconfigRaw, tsconfigDir, isolatedDeclarations, emitDtsOnly, vue, parallel, eager }) {
|
|
766
637
|
const dtsMap = new Map();
|
|
767
638
|
/**
|
|
768
639
|
* A map of input id to output file name
|
|
@@ -774,14 +645,20 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
|
|
|
774
645
|
* ])
|
|
775
646
|
*/
|
|
776
647
|
const inputAliasMap = new Map();
|
|
777
|
-
let
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
648
|
+
let childProcess;
|
|
649
|
+
let rpc;
|
|
650
|
+
let tscEmit;
|
|
651
|
+
if (parallel) {
|
|
652
|
+
childProcess = fork(new URL(WORKER_URL, import.meta.url), { stdio: "inherit" });
|
|
653
|
+
rpc = createBirpc({}, {
|
|
654
|
+
post: (data) => childProcess.send(data),
|
|
655
|
+
on: (fn) => childProcess.on("message", fn)
|
|
656
|
+
});
|
|
781
657
|
}
|
|
782
658
|
return {
|
|
783
659
|
name: "rolldown-plugin-dts:generate",
|
|
784
660
|
async buildStart(options) {
|
|
661
|
+
if (!parallel && (!isolatedDeclarations || vue)) ({tscEmit} = await import("./tsc-CeRgkVKp.js"));
|
|
785
662
|
if (!Array.isArray(options.input)) for (const [name, id] of Object.entries(options.input)) {
|
|
786
663
|
debug$1("resolving input alias %s -> %s", name, id);
|
|
787
664
|
let resolved = await this.resolve(id);
|
|
@@ -839,7 +716,7 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
|
|
|
839
716
|
include: [RE_DTS],
|
|
840
717
|
exclude: [RE_NODE_MODULES]
|
|
841
718
|
} },
|
|
842
|
-
handler(dtsId) {
|
|
719
|
+
async handler(dtsId) {
|
|
843
720
|
if (!dtsMap.has(dtsId)) return;
|
|
844
721
|
const { code, id, isEntry } = dtsMap.get(dtsId);
|
|
845
722
|
let dtsCode;
|
|
@@ -860,8 +737,18 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
|
|
|
860
737
|
map.sourcesContent = void 0;
|
|
861
738
|
}
|
|
862
739
|
} else {
|
|
863
|
-
const
|
|
864
|
-
const
|
|
740
|
+
const entries = eager ? void 0 : Array.from(dtsMap.values()).filter((v) => v.isEntry).map((v) => v.id);
|
|
741
|
+
const options = {
|
|
742
|
+
tsconfigRaw,
|
|
743
|
+
tsconfigDir,
|
|
744
|
+
entries,
|
|
745
|
+
id,
|
|
746
|
+
isEntry,
|
|
747
|
+
vue
|
|
748
|
+
};
|
|
749
|
+
let result;
|
|
750
|
+
if (parallel) result = await rpc.tscEmit(options);
|
|
751
|
+
else result = tscEmit(options);
|
|
865
752
|
if (result.error) return this.error(result.error);
|
|
866
753
|
dtsCode = result.code;
|
|
867
754
|
map = result.map;
|
|
@@ -877,7 +764,7 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
|
|
|
877
764
|
for (const fileName of Object.keys(bundle)) if (bundle[fileName].type === "chunk" && !RE_DTS.test(fileName) && !RE_DTS_MAP.test(fileName)) delete bundle[fileName];
|
|
878
765
|
} : void 0,
|
|
879
766
|
buildEnd() {
|
|
880
|
-
|
|
767
|
+
childProcess?.kill();
|
|
881
768
|
}
|
|
882
769
|
};
|
|
883
770
|
}
|
|
@@ -942,24 +829,28 @@ function dts(options = {}) {
|
|
|
942
829
|
plugins.push(createDtsResolvePlugin(resolved), createFakeJsPlugin(resolved));
|
|
943
830
|
return plugins;
|
|
944
831
|
}
|
|
945
|
-
function resolveOptions({ cwd = process.cwd(), tsconfig, compilerOptions = {}, isolatedDeclarations, sourcemap, dtsInput = false, emitDtsOnly = false, resolve = false, vue = false }) {
|
|
832
|
+
function resolveOptions({ cwd = process.cwd(), tsconfig, compilerOptions = {}, tsconfigRaw: overriddenTsconfigRaw = {}, isolatedDeclarations, sourcemap, dtsInput = false, emitDtsOnly = false, resolve = false, vue = false, parallel = false, eager = false }) {
|
|
833
|
+
let resolvedTsconfig;
|
|
946
834
|
if (tsconfig === true || tsconfig == null) {
|
|
947
835
|
const { config, path: path$1 } = getTsconfig(cwd) || {};
|
|
948
836
|
tsconfig = path$1;
|
|
949
|
-
|
|
950
|
-
...config?.compilerOptions,
|
|
951
|
-
...compilerOptions
|
|
952
|
-
};
|
|
837
|
+
resolvedTsconfig = config;
|
|
953
838
|
} else if (typeof tsconfig === "string") {
|
|
954
839
|
tsconfig = path.resolve(cwd || process.cwd(), tsconfig);
|
|
955
|
-
|
|
956
|
-
compilerOptions = {
|
|
957
|
-
...config.compilerOptions,
|
|
958
|
-
...compilerOptions
|
|
959
|
-
};
|
|
840
|
+
resolvedTsconfig = parseTsconfig(tsconfig);
|
|
960
841
|
} else tsconfig = void 0;
|
|
842
|
+
compilerOptions = {
|
|
843
|
+
...resolvedTsconfig?.compilerOptions,
|
|
844
|
+
...compilerOptions
|
|
845
|
+
};
|
|
961
846
|
sourcemap ??= !!compilerOptions.declarationMap;
|
|
962
847
|
compilerOptions.declarationMap = sourcemap;
|
|
848
|
+
const tsconfigRaw = {
|
|
849
|
+
...resolvedTsconfig,
|
|
850
|
+
...overriddenTsconfigRaw,
|
|
851
|
+
compilerOptions
|
|
852
|
+
};
|
|
853
|
+
const tsconfigDir = tsconfig ? path.dirname(tsconfig) : cwd;
|
|
963
854
|
if (isolatedDeclarations == null) isolatedDeclarations = !!compilerOptions?.isolatedDeclarations;
|
|
964
855
|
if (isolatedDeclarations === true) isolatedDeclarations = {};
|
|
965
856
|
if (isolatedDeclarations) {
|
|
@@ -969,13 +860,16 @@ function resolveOptions({ cwd = process.cwd(), tsconfig, compilerOptions = {}, i
|
|
|
969
860
|
return {
|
|
970
861
|
cwd,
|
|
971
862
|
tsconfig,
|
|
972
|
-
|
|
863
|
+
tsconfigDir,
|
|
864
|
+
tsconfigRaw,
|
|
973
865
|
isolatedDeclarations,
|
|
974
866
|
sourcemap,
|
|
975
867
|
dtsInput,
|
|
976
868
|
emitDtsOnly,
|
|
977
869
|
resolve,
|
|
978
|
-
vue
|
|
870
|
+
vue,
|
|
871
|
+
parallel,
|
|
872
|
+
eager
|
|
979
873
|
};
|
|
980
874
|
}
|
|
981
875
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import Debug from "debug";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/vue.ts
|
|
6
|
+
const debug$1 = Debug("rolldown-plugin-dts:vue");
|
|
7
|
+
let createVueProgram;
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
function loadVueLanguageTools() {
|
|
10
|
+
try {
|
|
11
|
+
const vueTscPath = require.resolve("vue-tsc");
|
|
12
|
+
const { proxyCreateProgram } = require(require.resolve("@volar/typescript", { paths: [vueTscPath] }));
|
|
13
|
+
const vue = require(require.resolve("@vue/language-core", { paths: [vueTscPath] }));
|
|
14
|
+
return {
|
|
15
|
+
proxyCreateProgram,
|
|
16
|
+
vue
|
|
17
|
+
};
|
|
18
|
+
} catch (error) {
|
|
19
|
+
debug$1("vue language tools not found", error);
|
|
20
|
+
throw new Error("Failed to load vue language tools. Please manually install vue-tsc.");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function createVueProgramFactory(ts$1) {
|
|
24
|
+
if (createVueProgram) return createVueProgram;
|
|
25
|
+
debug$1("loading vue language tools");
|
|
26
|
+
const { proxyCreateProgram, vue } = loadVueLanguageTools();
|
|
27
|
+
return createVueProgram = proxyCreateProgram(ts$1, ts$1.createProgram, (ts$2, options) => {
|
|
28
|
+
const { configFilePath } = options.options;
|
|
29
|
+
const vueOptions = typeof configFilePath === "string" ? vue.createParsedCommandLine(ts$2, ts$2.sys, configFilePath.replaceAll("\\", "/")).vueOptions : vue.getDefaultCompilerOptions();
|
|
30
|
+
const vueLanguagePlugin = vue.createVueLanguagePlugin(ts$2, options.options, vueOptions, (id) => id);
|
|
31
|
+
return { languagePlugins: [vueLanguagePlugin] };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/utils/tsc.ts
|
|
37
|
+
const debug = Debug("rolldown-plugin-dts:tsc");
|
|
38
|
+
debug(`loaded typescript: ${ts.version}`);
|
|
39
|
+
const programs = [];
|
|
40
|
+
const formatHost = {
|
|
41
|
+
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
|
|
42
|
+
getNewLine: () => ts.sys.newLine,
|
|
43
|
+
getCanonicalFileName: ts.sys.useCaseSensitiveFileNames ? (f) => f : (f) => f.toLowerCase()
|
|
44
|
+
};
|
|
45
|
+
const defaultCompilerOptions = {
|
|
46
|
+
declaration: true,
|
|
47
|
+
noEmit: false,
|
|
48
|
+
emitDeclarationOnly: true,
|
|
49
|
+
noEmitOnError: true,
|
|
50
|
+
checkJs: false,
|
|
51
|
+
declarationMap: false,
|
|
52
|
+
skipLibCheck: true,
|
|
53
|
+
target: 99,
|
|
54
|
+
resolveJsonModule: true,
|
|
55
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler
|
|
56
|
+
};
|
|
57
|
+
function createOrGetTsModule(options) {
|
|
58
|
+
const { id, isEntry } = options;
|
|
59
|
+
const program = programs.find((program$1) => {
|
|
60
|
+
if (isEntry) return program$1.getRootFileNames().includes(id);
|
|
61
|
+
return program$1.getSourceFile(id);
|
|
62
|
+
});
|
|
63
|
+
if (program) {
|
|
64
|
+
const sourceFile = program.getSourceFile(id);
|
|
65
|
+
if (sourceFile) return {
|
|
66
|
+
program,
|
|
67
|
+
file: sourceFile
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
debug(`create program for module: ${id}`);
|
|
71
|
+
const module = createTsProgram(options);
|
|
72
|
+
debug(`created program for module: ${id}`);
|
|
73
|
+
programs.push(module.program);
|
|
74
|
+
return module;
|
|
75
|
+
}
|
|
76
|
+
function createTsProgram({ entries, id, tsconfigRaw, tsconfigDir, vue }) {
|
|
77
|
+
const parsedCmd = ts.parseJsonConfigFileContent(tsconfigRaw, ts.sys, tsconfigDir);
|
|
78
|
+
const compilerOptions = {
|
|
79
|
+
...defaultCompilerOptions,
|
|
80
|
+
...parsedCmd.options
|
|
81
|
+
};
|
|
82
|
+
const rootNames = entries ? [...new Set([id, ...entries])] : parsedCmd.fileNames;
|
|
83
|
+
const host = ts.createCompilerHost(compilerOptions, true);
|
|
84
|
+
const createProgram = vue ? createVueProgramFactory(ts) : ts.createProgram;
|
|
85
|
+
const program = createProgram({
|
|
86
|
+
rootNames,
|
|
87
|
+
options: compilerOptions,
|
|
88
|
+
host,
|
|
89
|
+
projectReferences: parsedCmd.projectReferences
|
|
90
|
+
});
|
|
91
|
+
const sourceFile = program.getSourceFile(id);
|
|
92
|
+
if (!sourceFile) throw new Error(`Source file not found: ${id}`);
|
|
93
|
+
return {
|
|
94
|
+
program,
|
|
95
|
+
file: sourceFile
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function tscEmit(tscOptions) {
|
|
99
|
+
const module = createOrGetTsModule(tscOptions);
|
|
100
|
+
const { program, file } = module;
|
|
101
|
+
let dtsCode;
|
|
102
|
+
let map;
|
|
103
|
+
const { emitSkipped, diagnostics } = program.emit(
|
|
104
|
+
file,
|
|
105
|
+
(fileName, code) => {
|
|
106
|
+
if (fileName.endsWith(".map")) {
|
|
107
|
+
debug(`emit dts sourcemap: ${fileName}`);
|
|
108
|
+
map = JSON.parse(code);
|
|
109
|
+
} else {
|
|
110
|
+
debug(`emit dts: ${fileName}`);
|
|
111
|
+
dtsCode = code;
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
void 0,
|
|
115
|
+
true,
|
|
116
|
+
void 0,
|
|
117
|
+
// @ts-expect-error private API: forceDtsEmit
|
|
118
|
+
true
|
|
119
|
+
);
|
|
120
|
+
if (emitSkipped && diagnostics.length) return { error: ts.formatDiagnostics(diagnostics, formatHost) };
|
|
121
|
+
return {
|
|
122
|
+
code: dtsCode,
|
|
123
|
+
map
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
export { tscEmit };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { TsConfigJson } from "get-tsconfig";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/tsc.d.ts
|
|
5
|
+
|
|
6
|
+
interface TscOptions {
|
|
7
|
+
tsconfigRaw: TsConfigJson;
|
|
8
|
+
tsconfigDir: string;
|
|
9
|
+
entries?: string[];
|
|
10
|
+
id: string;
|
|
11
|
+
isEntry: boolean;
|
|
12
|
+
vue?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface TscResult {
|
|
15
|
+
code?: string;
|
|
16
|
+
map?: any;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
declare function tscEmit(tscOptions: TscOptions): TscResult; //#endregion
|
|
20
|
+
//#region src/utils/tsc-worker.d.ts
|
|
21
|
+
declare const functions: {
|
|
22
|
+
tscEmit: typeof tscEmit;
|
|
23
|
+
};
|
|
24
|
+
type TscFunctions = typeof functions;
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { TscFunctions };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { tscEmit } from "../tsc-H_wSbW_C.js";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { createBirpc } from "birpc";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/tsc-worker.ts
|
|
6
|
+
const functions = { tscEmit };
|
|
7
|
+
createBirpc(functions, {
|
|
8
|
+
post: (data) => process.send(data),
|
|
9
|
+
on: (fn) => process.on("message", fn)
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rolldown-plugin-dts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "A Rolldown plugin to bundle dts files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"@babel/parser": "^7.27.2",
|
|
46
46
|
"@babel/types": "^7.27.1",
|
|
47
47
|
"ast-kit": "^2.0.0",
|
|
48
|
+
"birpc": "^2.3.0",
|
|
48
49
|
"debug": "^4.4.1",
|
|
49
50
|
"dts-resolver": "^2.0.1",
|
|
50
51
|
"get-tsconfig": "^4.10.0"
|