rolldown-plugin-dts 0.12.3 → 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 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 where the the plugin will look for the `tsconfig.json` file.
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
- * When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
42
+ * Set to `true` if your entry files are `.d.ts` files instead of `.ts` files.
43
43
  *
44
- * If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
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
- * When `true`, the plugin will only emit `.d.ts` files and remove all other chunks.
49
+ * If `true`, the plugin will emit only `.d.ts` files and remove all other output chunks.
50
50
  *
51
- * This feature is particularly beneficial when you need to generate `d.ts` files for the CommonJS format as part of a separate build process.
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
- * When set to `false`, the plugin will ignore any `tsconfig.json` file.
59
- * However, `compilerOptions` can still be specified directly in the options.
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 `tsconfig.json`
61
+ * @default 'tsconfig.json'
62
62
  */
63
63
  tsconfig?: string | boolean
64
64
 
65
65
  /**
66
- * The `compilerOptions` for the TypeScript compiler.
66
+ * Pass a raw `tsconfig.json` object directly to the plugin.
67
67
  *
68
- * @see https://www.typescriptlang.org/docs/handbook/compiler-options.html
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
- * When `true`, the plugin will generate `.d.ts` files using Oxc,
74
- * which is blazingly faster than `typescript` compiler.
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
- * When `true`, the plugin will generate declaration maps for `.d.ts` files.
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
- /** Resolve external types used in dts files from `node_modules` */
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
- compilerOptions,
14
+ tsconfigRaw,
15
+ tsconfigDir,
15
16
  isolatedDeclarations,
16
17
  emitDtsOnly,
17
- vue
18
- }: Pick<OptionsResolved, "compilerOptions" | "isolatedDeclarations" | "emitDtsOnly" | "vue">): Plugin;
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 where the the plugin will look for the `tsconfig.json` file.
27
+ * The directory in which the plugin will search for the `tsconfig.json` file.
25
28
  */
26
29
  cwd?: string;
27
30
  /**
28
- * When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
31
+ * Set to `true` if your entry files are `.d.ts` files instead of `.ts` files.
29
32
  *
30
- * If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
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
- * When `true`, the plugin will only emit `.d.ts` files and remove all other chunks.
37
+ * If `true`, the plugin will emit only `.d.ts` files and remove all other output chunks.
35
38
  *
36
- * This feature is particularly beneficial when you need to generate `d.ts` files for the CommonJS format as part of a separate build process.
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
- * When set to `false`, the plugin will ignore any `tsconfig.json` file.
43
- * However, `compilerOptions` can still be specified directly in the options.
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 `tsconfig.json`
48
+ * @default 'tsconfig.json'
46
49
  */
47
50
  tsconfig?: string | boolean;
48
51
  /**
49
- * The `compilerOptions` for the TypeScript compiler.
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/docs/handbook/compiler-options.html
60
+ * @see https://www.typescriptlang.org/tsconfig/#compilerOptions
52
61
  */
53
62
  compilerOptions?: TsConfigJson.CompilerOptions;
54
63
  /**
55
- * When `true`, the plugin will generate `.d.ts` files using Oxc,
56
- * which is blazingly faster than `typescript` compiler.
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
- * When `true`, the plugin will generate declaration maps for `.d.ts` files.
71
+ * If `true`, the plugin will generate declaration maps (`.d.ts.map`) for `.d.ts` files.
63
72
  */
64
73
  sourcemap?: boolean;
65
- /** Resolve external types used in dts files from `node_modules` */
74
+ /**
75
+ * Resolve external types used in `.d.ts` files from `node_modules`.
76
+ */
66
77
  resolve?: boolean | (string | RegExp)[];
67
78
  /**
68
- * When `true`, the plugin will generate `.d.ts` via `vue-tsc`.
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
- }: Options): OptionsResolved;
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
 
@@ -628,153 +629,11 @@ function inheritNodeComments(oldNode, newNode) {
628
629
  }
629
630
  }
630
631
 
631
- //#endregion
632
- //#region src/utils/vue.ts
633
- const debug$3 = Debug("rolldown-plugin-dts:vue");
634
- let createVueProgram;
635
- const require = createRequire(import.meta.url);
636
- function loadVueLanguageTools() {
637
- try {
638
- const vueTscPath = require.resolve("vue-tsc");
639
- const { proxyCreateProgram } = require(require.resolve("@volar/typescript", { paths: [vueTscPath] }));
640
- const vue = require(require.resolve("@vue/language-core", { paths: [vueTscPath] }));
641
- return {
642
- proxyCreateProgram,
643
- vue
644
- };
645
- } catch (error) {
646
- debug$3("vue language tools not found", error);
647
- throw new Error("Failed to load vue language tools. Please manually install vue-tsc.");
648
- }
649
- }
650
- function createVueProgramFactory() {
651
- if (createVueProgram) return createVueProgram;
652
- debug$3("loading vue language tools");
653
- const { proxyCreateProgram, vue } = loadVueLanguageTools();
654
- return createVueProgram = proxyCreateProgram(ts, ts.createProgram, (ts$1, options) => {
655
- const { configFilePath } = options.options;
656
- const vueOptions = typeof configFilePath === "string" ? vue.createParsedCommandLine(ts$1, ts$1.sys, configFilePath.replaceAll("\\", "/")).vueOptions : vue.getDefaultCompilerOptions();
657
- const vueLanguagePlugin = vue.createVueLanguagePlugin(ts$1, options.options, vueOptions, (id) => id);
658
- return { languagePlugins: [vueLanguagePlugin] };
659
- });
660
- }
661
-
662
- //#endregion
663
- //#region src/utils/tsc.ts
664
- const debug$2 = Debug("rolldown-plugin-dts:tsc");
665
- let ts;
666
- let formatHost;
667
- function initTs() {
668
- debug$2("loading typescript");
669
- const require$1 = createRequire(import.meta.url);
670
- ts = require$1("typescript");
671
- formatHost = {
672
- getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
673
- getNewLine: () => ts.sys.newLine,
674
- getCanonicalFileName: ts.sys.useCaseSensitiveFileNames ? (f) => f : (f) => f.toLowerCase()
675
- };
676
- debug$2(`loaded typescript: ${ts.version}`);
677
- }
678
- const defaultCompilerOptions = {
679
- declaration: true,
680
- noEmit: false,
681
- emitDeclarationOnly: true,
682
- noEmitOnError: true,
683
- checkJs: false,
684
- declarationMap: false,
685
- skipLibCheck: true,
686
- target: 99,
687
- resolveJsonModule: true
688
- };
689
- function createOrGetTsModule(programs, compilerOptions, id, isEntry, dtsMap, vue) {
690
- const program = programs.find((program$1) => {
691
- if (isEntry) return program$1.getRootFileNames().includes(id);
692
- return program$1.getSourceFile(id);
693
- });
694
- if (program) {
695
- const sourceFile = program.getSourceFile(id);
696
- if (sourceFile) return {
697
- program,
698
- file: sourceFile
699
- };
700
- }
701
- debug$2(`create program for module: ${id}`);
702
- const module = createTsProgram(compilerOptions, dtsMap, id, vue);
703
- debug$2(`created program for module: ${id}`);
704
- programs.push(module.program);
705
- return module;
706
- }
707
- function createTsProgram(compilerOptions, dtsMap, id, vue) {
708
- const overrideCompilerOptions = ts.convertCompilerOptionsFromJson(compilerOptions, ".").options;
709
- const options = {
710
- ...defaultCompilerOptions,
711
- ...overrideCompilerOptions
712
- };
713
- const host = ts.createCompilerHost(options, true);
714
- const { readFile: _readFile, fileExists: _fileExists } = host;
715
- host.fileExists = (fileName) => {
716
- const module = getTsModule(dtsMap, fileName);
717
- if (module) return true;
718
- if (debug$2.enabled && !RE_NODE_MODULES.test(fileName)) debug$2(`file exists from fs: ${fileName}`);
719
- return _fileExists(fileName);
720
- };
721
- host.readFile = (fileName) => {
722
- const module = getTsModule(dtsMap, fileName);
723
- if (module) return module.code;
724
- if (debug$2.enabled && !RE_NODE_MODULES.test(fileName)) debug$2(`read file from fs: ${fileName}`);
725
- return _readFile(fileName);
726
- };
727
- const entries = [...new Set([...Array.from(dtsMap.values()).filter((v) => v.isEntry).map((v) => v.id), id])];
728
- const createProgram = vue ? createVueProgramFactory() : ts.createProgram;
729
- const program = createProgram({
730
- rootNames: entries,
731
- options,
732
- host
733
- });
734
- const sourceFile = program.getSourceFile(id);
735
- if (!sourceFile) throw new Error(`Source file not found: ${id}`);
736
- return {
737
- program,
738
- file: sourceFile
739
- };
740
- }
741
- function tscEmit(module) {
742
- const { program, file } = module;
743
- let dtsCode;
744
- let map;
745
- const { emitSkipped, diagnostics } = program.emit(
746
- file,
747
- (fileName, code) => {
748
- if (fileName.endsWith(".map")) {
749
- debug$2(`emit dts sourcemap: ${fileName}`);
750
- map = JSON.parse(code);
751
- } else {
752
- debug$2(`emit dts: ${fileName}`);
753
- dtsCode = code;
754
- }
755
- },
756
- void 0,
757
- true,
758
- void 0,
759
- // @ts-expect-error private API: forceDtsEmit
760
- true
761
- );
762
- if (emitSkipped && diagnostics.length) return { error: ts.formatDiagnostics(diagnostics, formatHost) };
763
- return {
764
- code: dtsCode,
765
- map
766
- };
767
- }
768
- function getTsModule(dtsMap, tsId) {
769
- const module = Array.from(dtsMap.values()).find((dts$1) => dts$1.id === tsId);
770
- if (!module) return;
771
- return module;
772
- }
773
-
774
632
  //#endregion
775
633
  //#region src/generate.ts
776
634
  const debug$1 = Debug("rolldown-plugin-dts:generate");
777
- function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emitDtsOnly = false, vue }) {
635
+ const WORKER_URL = "./utils/tsc-worker.js";
636
+ function createGeneratePlugin({ tsconfigRaw, tsconfigDir, isolatedDeclarations, emitDtsOnly, vue, parallel, eager }) {
778
637
  const dtsMap = new Map();
779
638
  /**
780
639
  * A map of input id to output file name
@@ -786,14 +645,20 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
786
645
  * ])
787
646
  */
788
647
  const inputAliasMap = new Map();
789
- let programs = [];
790
- if (vue || !isolatedDeclarations) {
791
- initTs();
792
- if (vue) createVueProgramFactory();
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
+ });
793
657
  }
794
658
  return {
795
659
  name: "rolldown-plugin-dts:generate",
796
660
  async buildStart(options) {
661
+ if (!parallel && (!isolatedDeclarations || vue)) ({tscEmit} = await import("./tsc-CeRgkVKp.js"));
797
662
  if (!Array.isArray(options.input)) for (const [name, id] of Object.entries(options.input)) {
798
663
  debug$1("resolving input alias %s -> %s", name, id);
799
664
  let resolved = await this.resolve(id);
@@ -851,7 +716,7 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
851
716
  include: [RE_DTS],
852
717
  exclude: [RE_NODE_MODULES]
853
718
  } },
854
- handler(dtsId) {
719
+ async handler(dtsId) {
855
720
  if (!dtsMap.has(dtsId)) return;
856
721
  const { code, id, isEntry } = dtsMap.get(dtsId);
857
722
  let dtsCode;
@@ -872,8 +737,18 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
872
737
  map.sourcesContent = void 0;
873
738
  }
874
739
  } else {
875
- const module = createOrGetTsModule(programs, compilerOptions, id, isEntry, dtsMap, vue);
876
- const result = tscEmit(module);
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);
877
752
  if (result.error) return this.error(result.error);
878
753
  dtsCode = result.code;
879
754
  map = result.map;
@@ -889,7 +764,7 @@ function createGeneratePlugin({ compilerOptions = {}, isolatedDeclarations, emit
889
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];
890
765
  } : void 0,
891
766
  buildEnd() {
892
- programs = [];
767
+ childProcess?.kill();
893
768
  }
894
769
  };
895
770
  }
@@ -954,24 +829,28 @@ function dts(options = {}) {
954
829
  plugins.push(createDtsResolvePlugin(resolved), createFakeJsPlugin(resolved));
955
830
  return plugins;
956
831
  }
957
- 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;
958
834
  if (tsconfig === true || tsconfig == null) {
959
835
  const { config, path: path$1 } = getTsconfig(cwd) || {};
960
836
  tsconfig = path$1;
961
- compilerOptions = {
962
- ...config?.compilerOptions,
963
- ...compilerOptions
964
- };
837
+ resolvedTsconfig = config;
965
838
  } else if (typeof tsconfig === "string") {
966
839
  tsconfig = path.resolve(cwd || process.cwd(), tsconfig);
967
- const config = parseTsconfig(tsconfig);
968
- compilerOptions = {
969
- ...config.compilerOptions,
970
- ...compilerOptions
971
- };
840
+ resolvedTsconfig = parseTsconfig(tsconfig);
972
841
  } else tsconfig = void 0;
842
+ compilerOptions = {
843
+ ...resolvedTsconfig?.compilerOptions,
844
+ ...compilerOptions
845
+ };
973
846
  sourcemap ??= !!compilerOptions.declarationMap;
974
847
  compilerOptions.declarationMap = sourcemap;
848
+ const tsconfigRaw = {
849
+ ...resolvedTsconfig,
850
+ ...overriddenTsconfigRaw,
851
+ compilerOptions
852
+ };
853
+ const tsconfigDir = tsconfig ? path.dirname(tsconfig) : cwd;
975
854
  if (isolatedDeclarations == null) isolatedDeclarations = !!compilerOptions?.isolatedDeclarations;
976
855
  if (isolatedDeclarations === true) isolatedDeclarations = {};
977
856
  if (isolatedDeclarations) {
@@ -981,13 +860,16 @@ function resolveOptions({ cwd = process.cwd(), tsconfig, compilerOptions = {}, i
981
860
  return {
982
861
  cwd,
983
862
  tsconfig,
984
- compilerOptions,
863
+ tsconfigDir,
864
+ tsconfigRaw,
985
865
  isolatedDeclarations,
986
866
  sourcemap,
987
867
  dtsInput,
988
868
  emitDtsOnly,
989
869
  resolve,
990
- vue
870
+ vue,
871
+ parallel,
872
+ eager
991
873
  };
992
874
  }
993
875
 
@@ -0,0 +1,3 @@
1
+ import { tscEmit } from "./tsc-H_wSbW_C.js";
2
+
3
+ export { tscEmit };
@@ -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.12.3",
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"