rsbuild-plugin-dts 0.0.18 → 0.1.1

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
@@ -2,13 +2,166 @@
2
2
  <img alt="Rslib Banner" src="https://assets.rspack.dev/rslib/rslib-banner.png">
3
3
  </picture>
4
4
 
5
- # Rslib
5
+ # rsbuild-plugin-dts
6
6
 
7
- Rslib is a library development tool powered by [Rsbuild](https://rsbuild.dev). It allows library developers to leverage the knowledge and ecosystem of webpack and Rspack.
7
+ An [Rsbuild plugin](https://www.npmjs.com/package/rsbuild-plugin-dts) to emit declaration files for TypeScript which is built-in in Rslib.
8
8
 
9
- ## Documentation
9
+ ## Using in Rslib
10
10
 
11
- https://lib.rsbuild.dev/
11
+ Read [DTS](https://lib.rsbuild.dev/guide/advanced/dts) and [lib.dts](https://lib.rsbuild.dev/config/lib/dts) for more details.
12
+
13
+ ## Using in Rsbuild
14
+
15
+ Install:
16
+
17
+ ```bash
18
+ npm add rsbuild-plugin-dts -D
19
+ ```
20
+
21
+ Add plugin to `rsbuild.config.ts`:
22
+
23
+ ```ts
24
+ // rsbuild.config.ts
25
+ import { pluginDts } from 'rsbuild-plugin-dts';
26
+
27
+ export default {
28
+ plugins: [pluginDts()],
29
+ };
30
+ ```
31
+
32
+ ## Options
33
+
34
+ ### bundle
35
+
36
+ - **Type:** `boolean`
37
+ - **Default:** `false`
38
+
39
+ Whether to bundle the DTS files.
40
+
41
+ If you want to [bundle DTS](https://lib.rsbuild.dev/guide/advanced/dts#bundle-dts) files, you should:
42
+
43
+ 1. Install `@microsoft/api-extractor` as a development dependency, which is the underlying tool used for bundling DTS files.
44
+
45
+ ```bash
46
+ npm add @microsoft/api-extractor -D
47
+ ```
48
+
49
+ 2. Set `bundle` to `true`.
50
+
51
+ ```js
52
+ pluginDts({
53
+ bundle: true,
54
+ });
55
+ ```
56
+
57
+ ### distPath
58
+
59
+ - **Type:** `string`
60
+
61
+ The output directory of DTS files. The default value follows the priority below:
62
+
63
+ 1. The `distPath` value of the plugin options.
64
+ 2. The `declarationDir` value in the `tsconfig.json` file.
65
+ 3. The [output.distPath.root](https://rsbuild.dev/config/output/dist-path) value of Rsbuild configuration.
66
+
67
+ ```js
68
+ pluginDts({
69
+ distPath: './dist-types',
70
+ });
71
+ ```
72
+
73
+ ### build
74
+
75
+ - **Type:** `boolean`
76
+ - **Default:** `false`
77
+
78
+ Determines whether to generate DTS files while building the project references. This is equivalent to using the `--build` flag with the `tsc` command. See [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) for more details.
79
+
80
+ When this option is enabled, you must explicitly set `declarationDir` or `outDir` in `tsconfig.json` in order to meet the build requirements.
81
+
82
+ ### abortOnError
83
+
84
+ - **Type:** `boolean`
85
+ - **Default:** `true`
86
+
87
+ Whether to abort the build process when an error occurs during DTS generation.
88
+
89
+ By default, type errors will cause the build to fail.
90
+
91
+ When `abortOnError` is set to `false`, the build will still succeed even if there are type issues in the code.
92
+
93
+ ```js
94
+ pluginDts({
95
+ abortOnError: false,
96
+ });
97
+ ```
98
+
99
+ ### dtsExtension
100
+
101
+ - **Type:** `string`
102
+ - **Default:** `'.d.ts'`
103
+
104
+ The extension of the DTS file.
105
+
106
+ ```js
107
+ pluginDts({
108
+ dtsExtension: '.d.mts',
109
+ });
110
+ ```
111
+
112
+ ### autoExternal
113
+
114
+ - **Type:** `boolean`
115
+ - **Default:** `true`
116
+
117
+ Whether to automatically externalize dependencies of different dependency types and do not bundle them into the DTS file.
118
+
119
+ The default value of `autoExternal` is `true`, which means the following dependency types will not be bundled:
120
+
121
+ - `dependencies`
122
+ - `optionalDependencies`
123
+ - `peerDependencies`
124
+
125
+ And the following dependency types will be bundled:
126
+
127
+ - `devDependencies`
128
+
129
+ ```js
130
+ pluginDts({
131
+ autoExternal: {
132
+ dependencies: true,
133
+ optionalDependencies: true,
134
+ peerDependencies: true,
135
+ devDependencies: false,
136
+ },
137
+ });
138
+ ```
139
+
140
+ ### banner
141
+
142
+ - **Type:** `string`
143
+ - **Default:** `undefined`
144
+
145
+ Inject content into the top of each DTS file.
146
+
147
+ ```js
148
+ pluginDts({
149
+ banner: '/** @banner */',
150
+ });
151
+ ```
152
+
153
+ ### footer
154
+
155
+ - **Type:** `string`
156
+ - **Default:** `undefined`
157
+
158
+ Inject content into the bottom of each DTS file.
159
+
160
+ ```js
161
+ pluginDts({
162
+ footer: '/** @footer */',
163
+ });
164
+ ```
12
165
 
13
166
  ## Contributing
14
167
 
@@ -16,4 +169,4 @@ Please read the [Contributing Guide](https://github.com/web-infra-dev/rslib/blob
16
169
 
17
170
  ## License
18
171
 
19
- Rslib is [MIT licensed](https://github.com/web-infra-dev/rslib/blob/main/LICENSE).
172
+ [MIT licensed](https://github.com/web-infra-dev/rslib/blob/main/LICENSE).
@@ -2,7 +2,7 @@ import type { DtsEntry } from './index';
2
2
  export type BundleOptions = {
3
3
  name: string;
4
4
  cwd: string;
5
- outDir: string;
5
+ distPath: string;
6
6
  dtsExtension: string;
7
7
  banner?: string;
8
8
  footer?: string;
@@ -4,14 +4,14 @@ import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core__ from "@rsbuild/core";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
5
5
  import * as __WEBPACK_EXTERNAL_MODULE__utils_js__ from "./utils.js";
6
6
  async function bundleDts(options) {
7
- const { name, cwd, outDir, dtsExtension, banner, footer, dtsEntry = {
7
+ const { name, cwd, distPath, dtsExtension, banner, footer, dtsEntry = {
8
8
  name: 'index',
9
9
  path: 'index.d.ts'
10
10
  }, tsconfigPath = 'tsconfig.json', bundledPackages = [] } = options;
11
11
  try {
12
12
  const start = Date.now();
13
- const untrimmedFilePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(cwd, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.relative)(cwd, outDir), `${dtsEntry.name}${dtsExtension}`);
14
- const mainEntryPointFilePath = dtsEntry.path;
13
+ const untrimmedFilePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(cwd, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.relative)(cwd, distPath), `${dtsEntry.name}${dtsExtension}`);
14
+ const mainEntryPointFilePath = dtsEntry.path.replace(/\?.*$/, '');
15
15
  const internalConfig = {
16
16
  mainEntryPointFilePath,
17
17
  bundledPackages,
@@ -20,7 +20,7 @@ async function bundleDts(options) {
20
20
  untrimmedFilePath
21
21
  },
22
22
  compiler: {
23
- tsconfigFilePath: tsconfigPath.includes(cwd) ? tsconfigPath : (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(cwd, tsconfigPath)
23
+ tsconfigFilePath: tsconfigPath
24
24
  },
25
25
  projectFolder: cwd
26
26
  };
package/dist/dts.js CHANGED
@@ -2,7 +2,6 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_fs__ from "node:fs";
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_node_path__ from "node:path";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core__ from "@rsbuild/core";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
5
- import * as __WEBPACK_EXTERNAL_MODULE_typescript__ from "typescript";
6
5
  import * as __WEBPACK_EXTERNAL_MODULE__tsc_js__ from "./tsc.js";
7
6
  import * as __WEBPACK_EXTERNAL_MODULE__utils_js__ from "./utils.js";
8
7
  const isObject = (obj)=>'[object Object]' === Object.prototype.toString.call(obj);
@@ -56,39 +55,31 @@ const calcBundledPackages = (options)=>{
56
55
  return Array.from(new Set(bundledPackages));
57
56
  };
58
57
  async function generateDts(data) {
59
- const { bundle, distPath, dtsEntry, tsconfigPath, name, cwd, build, isWatch, dtsExtension = '.d.ts', autoExternal = true, userExternals, banner, footer } = data;
58
+ const { bundle, dtsEmitPath, dtsEntry, tsconfigPath, tsConfigResult, name, cwd, build, isWatch, dtsExtension = '.d.ts', autoExternal = true, userExternals, banner, footer } = data;
60
59
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.start(`Generating DTS... ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
61
- const configPath = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].findConfigFile(cwd, __WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys.fileExists, tsconfigPath);
62
- if (!configPath) {
63
- __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(`tsconfig.json not found in ${cwd}`);
64
- throw new Error();
65
- }
66
- const { options: rawCompilerOptions, fileNames } = (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.loadTsconfig)(configPath);
60
+ const { options: rawCompilerOptions, fileNames } = tsConfigResult;
67
61
  // The longest common path of all non-declaration input files.
68
62
  // If composite is set, the default is instead the directory containing the tsconfig.json file.
69
63
  // see https://www.typescriptlang.org/tsconfig/#rootDir
70
- const rootDir = rawCompilerOptions.rootDir ?? (rawCompilerOptions.composite ? (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(configPath) : await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.calcLongestCommonPath)(fileNames.filter((fileName)=>!/\.d\.(ts|mts|cts)$/.test(fileName)))) ?? (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(configPath);
71
- const outDir = distPath ? distPath : rawCompilerOptions.declarationDir || './dist';
64
+ const rootDir = rawCompilerOptions.rootDir ?? (rawCompilerOptions.composite ? (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(tsconfigPath) : await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.calcLongestCommonPath)(fileNames.filter((fileName)=>!/\.d\.(ts|mts|cts)$/.test(fileName)))) ?? (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(tsconfigPath);
65
+ const resolvedDtsEmitPath = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.resolve)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(tsconfigPath), dtsEmitPath));
72
66
  if (build) {
73
67
  // do not allow to use bundle DTS when 'build: true' since temp declarationDir should be set by user in tsconfig
74
68
  if (bundle) throw Error('Can not set "dts.bundle: true" when "dts.build: true"');
75
69
  // can not set '--declarationDir' or '--outDir' when 'build: true'.
76
- if ((!rawCompilerOptions.outDir || (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)(rawCompilerOptions.outDir) !== (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.resolve)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(configPath), outDir))) && (!rawCompilerOptions.declarationDir || (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)(rawCompilerOptions.declarationDir) !== (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.resolve)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(configPath), outDir)))) {
70
+ if ((!rawCompilerOptions.outDir || (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)(rawCompilerOptions.outDir) !== resolvedDtsEmitPath) && (!rawCompilerOptions.declarationDir || (0, __WEBPACK_EXTERNAL_MODULE_node_path__.normalize)(rawCompilerOptions.declarationDir) !== resolvedDtsEmitPath)) {
77
71
  const info = rawCompilerOptions.outDir && !rawCompilerOptions.declarationDir ? 'outDir' : 'declarationDir';
78
- throw Error(`Please set ${info}: "${outDir}" in ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].underline(configPath)} to keep it same as "dts.distPath" or "output.distPath" field in lib config.`);
72
+ throw Error(`Please set ${info}: "${dtsEmitPath}" in ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].underline(tsconfigPath)} to keep it same as "dts.distPath" or "output.distPath.root" field in lib config.`);
79
73
  }
80
74
  }
81
- const getDeclarationDir = (bundle, distPath)=>{
82
- if (bundle) return (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.ensureTempDeclarationDir)(cwd);
83
- return distPath ? distPath : rawCompilerOptions.declarationDir ?? './dist';
84
- };
85
- const declarationDir = getDeclarationDir(bundle, distPath);
75
+ const declarationDir = bundle ? (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.ensureTempDeclarationDir)(cwd, name) : dtsEmitPath;
86
76
  const { name: entryName, path: entryPath } = dtsEntry;
87
77
  let entry = '';
88
78
  if (true === bundle && entryPath) {
89
79
  const entrySourcePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.isAbsolute)(entryPath) ? entryPath : (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(cwd, entryPath);
90
80
  const relativePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.relative)(rootDir, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(entrySourcePath));
91
- entry = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(declarationDir, relativePath, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.basename)(entrySourcePath)).replace(/\.(js|mjs|jsx|ts|mts|tsx|cjs|cts|cjsx|ctsx|mjsx|mtsx)$/, '.d.ts');
81
+ entry = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(declarationDir, relativePath, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.basename)(entrySourcePath)) // Remove query in file path, such as RSLIB_ENTRY_QUERY.
82
+ .replace(/\?.*$/, '').replace(/\.(js|mjs|jsx|ts|mts|tsx|cjs|cts|cjsx|ctsx|mjsx|mtsx)$/, '.d.ts');
92
83
  }
93
84
  const bundleDtsIfNeeded = async ()=>{
94
85
  if (true === bundle) {
@@ -96,7 +87,7 @@ async function generateDts(data) {
96
87
  await bundleDts({
97
88
  name,
98
89
  cwd,
99
- outDir,
90
+ distPath: dtsEmitPath,
100
91
  dtsEntry: {
101
92
  name: entryName,
102
93
  path: entry
@@ -119,7 +110,8 @@ async function generateDts(data) {
119
110
  await (0, __WEBPACK_EXTERNAL_MODULE__tsc_js__.emitDts)({
120
111
  name,
121
112
  cwd,
122
- configPath,
113
+ configPath: tsconfigPath,
114
+ tsConfigResult,
123
115
  declarationDir,
124
116
  dtsExtension,
125
117
  banner,
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type RsbuildConfig, type RsbuildPlugin } from '@rsbuild/core';
2
+ import ts from 'typescript';
2
3
  export type PluginDtsOptions = {
3
4
  bundle?: boolean;
4
5
  distPath?: string;
@@ -22,9 +23,11 @@ export type DtsGenOptions = PluginDtsOptions & {
22
23
  cwd: string;
23
24
  isWatch: boolean;
24
25
  dtsEntry: DtsEntry;
26
+ dtsEmitPath: string;
25
27
  build?: boolean;
26
- tsconfigPath?: string;
28
+ tsconfigPath: string;
29
+ tsConfigResult: ts.ParsedCommandLine;
27
30
  userExternals?: NonNullable<RsbuildConfig['output']>['externals'];
28
31
  };
29
32
  export declare const PLUGIN_DTS_NAME = "rsbuild:dts";
30
- export declare const pluginDts: (options: PluginDtsOptions) => RsbuildPlugin;
33
+ export declare const pluginDts: (options?: PluginDtsOptions) => RsbuildPlugin;
package/dist/index.js CHANGED
@@ -2,14 +2,15 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_child_process__ from "node:child_proc
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_node_path__ from "node:path";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE_node_url__ from "node:url";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core__ from "@rsbuild/core";
5
+ import * as __WEBPACK_EXTERNAL_MODULE_typescript__ from "typescript";
5
6
  import * as __WEBPACK_EXTERNAL_MODULE__utils_js__ from "./utils.js";
6
- const src_filename = (0, __WEBPACK_EXTERNAL_MODULE_node_url__.fileURLToPath)(import.meta.url);
7
- const src_dirname = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(src_filename);
7
+ const src_rslib_entry_filename = (0, __WEBPACK_EXTERNAL_MODULE_node_url__.fileURLToPath)(import.meta.url);
8
+ const src_rslib_entry_dirname = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(src_rslib_entry_filename);
8
9
  const PLUGIN_DTS_NAME = 'rsbuild:dts';
9
10
  // use ts compiler API to generate bundleless dts
10
11
  // use ts compiler API and api-extractor to generate dts bundle
11
12
  // TODO: deal alias in dts
12
- const pluginDts = (options)=>({
13
+ const pluginDts = (options = {})=>({
13
14
  name: PLUGIN_DTS_NAME,
14
15
  setup (api) {
15
16
  options.bundle = options.bundle ?? false;
@@ -17,24 +18,42 @@ const pluginDts = (options)=>({
17
18
  options.build = options.build ?? false;
18
19
  const dtsPromises = [];
19
20
  let promisesResult = [];
20
- api.onBeforeEnvironmentCompile(({ isWatch, isFirstCompile, environment })=>{
21
+ let childProcesses = [];
22
+ api.onBeforeEnvironmentCompile(async ({ isWatch, isFirstCompile, environment })=>{
21
23
  if (!isFirstCompile) return;
22
24
  const { config } = environment;
23
- options.distPath = options.distPath ?? config.output?.distPath?.root;
24
- const jsExtension = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.extname)(src_filename);
25
- const childProcess = (0, __WEBPACK_EXTERNAL_MODULE_node_child_process__.fork)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(src_dirname, `./dts${jsExtension}`), [], {
26
- stdio: 'inherit'
27
- });
28
25
  // TODO: @microsoft/api-extractor only support single entry to bundle DTS
29
26
  // use first element of Record<string, string> type entry config
30
27
  const dtsEntry = (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.processSourceEntry)(options.bundle, config.source?.entry);
28
+ const cwd = api.context.rootPath;
29
+ const tsconfigPath = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].findConfigFile(cwd, __WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys.fileExists, config.source.tsconfigPath);
30
+ if (!tsconfigPath) {
31
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(`tsconfig.json not found in ${cwd}`);
32
+ throw new Error();
33
+ }
34
+ const tsConfigResult = (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.loadTsconfig)(tsconfigPath);
35
+ const dtsEmitPath = options.distPath ?? tsConfigResult.options.declarationDir ?? config.output?.distPath?.root;
36
+ const jsExtension = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.extname)(src_rslib_entry_filename);
37
+ const childProcess = (0, __WEBPACK_EXTERNAL_MODULE_node_child_process__.fork)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(src_rslib_entry_dirname, `./dts${jsExtension}`), [], {
38
+ stdio: 'inherit'
39
+ });
40
+ childProcesses.push(childProcess);
41
+ const { cleanDistPath } = config.output;
42
+ // clean dts files
43
+ if (false !== cleanDistPath) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.cleanDtsFiles)(dtsEmitPath);
44
+ // clean .rslib temp folder
45
+ if (options.bundle) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.clearTempDeclarationDir)(cwd);
46
+ // clean tsbuildinfo file
47
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.cleanTsBuildInfoFile)(tsconfigPath, tsConfigResult);
31
48
  const dtsGenOptions = {
32
49
  ...options,
33
50
  dtsEntry,
51
+ dtsEmitPath,
34
52
  userExternals: config.output.externals,
35
- tsconfigPath: config.source.tsconfigPath,
53
+ tsconfigPath,
54
+ tsConfigResult,
36
55
  name: environment.name,
37
- cwd: api.context.rootPath,
56
+ cwd,
38
57
  isWatch
39
58
  };
40
59
  childProcess.send(dtsGenOptions);
@@ -65,6 +84,12 @@ const pluginDts = (options)=>({
65
84
  },
66
85
  order: 'post'
67
86
  });
87
+ const killProcesses = ()=>{
88
+ for (const childProcess of childProcesses)if (!childProcess.killed) childProcess.kill();
89
+ childProcesses = [];
90
+ };
91
+ api.onCloseBuild(killProcesses);
92
+ api.onCloseDevServer(killProcesses);
68
93
  }
69
94
  });
70
95
  export { PLUGIN_DTS_NAME, pluginDts };
package/dist/tsc.d.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import ts from 'typescript';
1
2
  export type EmitDtsOptions = {
2
3
  name: string;
3
4
  cwd: string;
4
5
  configPath: string;
6
+ tsConfigResult: ts.ParsedCommandLine;
5
7
  declarationDir: string;
6
8
  dtsExtension: string;
7
9
  banner?: string;
package/dist/tsc.js CHANGED
@@ -2,13 +2,27 @@ import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core__ from "@rsbuild/core";
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE_typescript__ from "typescript";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE__utils_js__ from "./utils.js";
5
+ async function handleDiagnosticsAndProcessFiles(diagnostics, configPath, host, bundle, declarationDir, dtsExtension, banner, footer, name) {
6
+ const diagnosticMessages = [];
7
+ for (const diagnostic of diagnostics){
8
+ const fileLoc = (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.getFileLoc)(diagnostic, configPath);
9
+ const message = `${fileLoc} - ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].red('error')} ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`TS${diagnostic.code}:`)} ${__WEBPACK_EXTERNAL_MODULE_typescript__["default"].flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}`;
10
+ diagnosticMessages.push(message);
11
+ }
12
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
13
+ if (diagnosticMessages.length) {
14
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(`Failed to emit declaration files. ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
15
+ for (const message of diagnosticMessages)__WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(message);
16
+ throw new Error('DTS generation failed');
17
+ }
18
+ }
5
19
  async function emitDts(options, onComplete, bundle = false, isWatch = false, build = false) {
6
20
  const start = Date.now();
7
- const { configPath, declarationDir, name, dtsExtension, banner, footer } = options;
8
- const configFileParseResult = (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.loadTsconfig)(configPath);
9
- const { options: rawCompilerOptions, fileNames, projectReferences } = configFileParseResult;
21
+ const { configPath, tsConfigResult, declarationDir, name, dtsExtension, banner, footer } = options;
22
+ const { options: rawCompilerOptions, fileNames, projectReferences } = tsConfigResult;
10
23
  const compilerOptions = {
11
24
  ...rawCompilerOptions,
25
+ configFilePath: configPath,
12
26
  noEmit: false,
13
27
  declaration: true,
14
28
  declarationDir,
@@ -47,10 +61,11 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
47
61
  const system = {
48
62
  ...__WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys
49
63
  };
64
+ // build mode
50
65
  if (isWatch) {
51
- // watch mode
66
+ // watch mode, can also deal with incremental build
52
67
  if (build) {
53
- // incremental build with project references
68
+ // incremental build watcher with build project references
54
69
  const host = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createSolutionBuilderWithWatchHost(system, createProgram, reportDiagnostic, void 0, reportWatchStatusChanged);
55
70
  const solutionBuilder = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createSolutionBuilderWithWatch(host, [
56
71
  configPath
@@ -63,22 +78,39 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
63
78
  __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createWatchProgram(host);
64
79
  }
65
80
  } else {
66
- // build mode
67
- if (build) {
68
- // incremental build with project references
69
- let errorNumber = 0;
70
- const reportErrorSummary = (errorCount)=>{
71
- errorNumber = errorCount;
72
- };
73
- const host = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createSolutionBuilderHost(system, createProgram, reportDiagnostic, void 0, reportErrorSummary);
74
- const solutionBuilder = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createSolutionBuilder(host, [
75
- configPath
76
- ], compilerOptions);
77
- solutionBuilder.build();
78
- await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
79
- if (errorNumber > 0) {
80
- __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(`Failed to emit declaration files. ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
81
- throw new Error('DTS generation failed');
81
+ // normal build - npx tsc
82
+ if (build || compilerOptions.composite) {
83
+ if (!build && compilerOptions.composite) {
84
+ // incremental build with composite true - npx tsc
85
+ const host = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createIncrementalCompilerHost(compilerOptions);
86
+ const program = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createIncrementalProgram({
87
+ rootNames: fileNames,
88
+ options: compilerOptions,
89
+ configFileParsingDiagnostics: __WEBPACK_EXTERNAL_MODULE_typescript__["default"].getConfigFileParsingDiagnostics(tsConfigResult),
90
+ projectReferences,
91
+ host,
92
+ createProgram
93
+ });
94
+ program.emit();
95
+ const allDiagnostics = program.getSemanticDiagnostics().concat(program.getConfigFileParsingDiagnostics());
96
+ await handleDiagnosticsAndProcessFiles(allDiagnostics, configPath, host, bundle, declarationDir, dtsExtension, banner, footer, name);
97
+ } else {
98
+ // incremental build with build project references
99
+ // The equivalent of the `--build` flag for the tsc command.
100
+ let errorNumber = 0;
101
+ const reportErrorSummary = (errorCount)=>{
102
+ errorNumber = errorCount;
103
+ };
104
+ const host = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createSolutionBuilderHost(system, createProgram, reportDiagnostic, void 0, reportErrorSummary);
105
+ const solutionBuilder = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createSolutionBuilder(host, [
106
+ configPath
107
+ ], compilerOptions);
108
+ solutionBuilder.build();
109
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
110
+ if (errorNumber > 0) {
111
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(`Failed to emit declaration files. ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
112
+ throw new Error('DTS generation failed');
113
+ }
82
114
  }
83
115
  } else {
84
116
  const host = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].createCompilerHost(compilerOptions);
@@ -87,22 +119,11 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
87
119
  options: compilerOptions,
88
120
  projectReferences,
89
121
  host,
90
- configFileParsingDiagnostics: __WEBPACK_EXTERNAL_MODULE_typescript__["default"].getConfigFileParsingDiagnostics(configFileParseResult)
122
+ configFileParsingDiagnostics: __WEBPACK_EXTERNAL_MODULE_typescript__["default"].getConfigFileParsingDiagnostics(tsConfigResult)
91
123
  });
92
124
  const emitResult = program.emit();
93
125
  const allDiagnostics = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
94
- const diagnosticMessages = [];
95
- for (const diagnostic of allDiagnostics){
96
- const fileLoc = (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.getFileLoc)(diagnostic, configPath);
97
- const message = `${fileLoc} - ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].red('error')} ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`TS${diagnostic.code}:`)} ${__WEBPACK_EXTERNAL_MODULE_typescript__["default"].flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}`;
98
- diagnosticMessages.push(message);
99
- }
100
- await (0, __WEBPACK_EXTERNAL_MODULE__utils_js__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
101
- if (diagnosticMessages.length) {
102
- __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(`Failed to emit declaration files. ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
103
- for (const message of diagnosticMessages)__WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.error(message);
104
- throw new Error('DTS generation failed');
105
- }
126
+ await handleDiagnosticsAndProcessFiles(allDiagnostics, configPath, host, bundle, declarationDir, dtsExtension, banner, footer, name);
106
127
  }
107
128
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.ready(`DTS generated in ${(0, __WEBPACK_EXTERNAL_MODULE__utils_js__.getTimeCost)(start)} ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
108
129
  }
package/dist/utils.d.ts CHANGED
@@ -4,7 +4,10 @@ import type { DtsEntry } from './index';
4
4
  export declare function loadTsconfig(tsconfigPath: string): ts.ParsedCommandLine;
5
5
  export declare const TEMP_FOLDER = ".rslib";
6
6
  export declare const TEMP_DTS_DIR: string;
7
- export declare function ensureTempDeclarationDir(cwd: string): string;
7
+ export declare function ensureTempDeclarationDir(cwd: string, name: string): string;
8
+ export declare function pathExists(path: string): Promise<boolean>;
9
+ export declare function emptyDir(dir: string): Promise<void>;
10
+ export declare function clearTempDeclarationDir(cwd: string): Promise<void>;
8
11
  export declare function getFileLoc(diagnostic: ts.Diagnostic, configPath: string): string;
9
12
  export declare const prettyTime: (seconds: number) => string;
10
13
  export declare function getTimeCost(start: number): string;
@@ -12,3 +15,5 @@ export declare function addBannerAndFooter(file: string, banner?: string, footer
12
15
  export declare function processDtsFiles(bundle: boolean, dir: string, dtsExtension: string, banner?: string, footer?: string): Promise<void>;
13
16
  export declare function processSourceEntry(bundle: boolean, entryConfig: NonNullable<RsbuildConfig['source']>['entry']): DtsEntry;
14
17
  export declare function calcLongestCommonPath(absPaths: string[]): Promise<string | null>;
18
+ export declare function cleanDtsFiles(dir: string): Promise<void>;
19
+ export declare function cleanTsBuildInfoFile(tsconfigPath: string, tsConfigResult: ts.ParsedCommandLine): Promise<void>;
package/dist/utils.js CHANGED
@@ -14,8 +14,8 @@ function loadTsconfig(tsconfigPath) {
14
14
  }
15
15
  const TEMP_FOLDER = '.rslib';
16
16
  const TEMP_DTS_DIR = `${TEMP_FOLDER}/declarations`;
17
- function ensureTempDeclarationDir(cwd) {
18
- const dirPath = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].join(cwd, TEMP_DTS_DIR);
17
+ function ensureTempDeclarationDir(cwd, name) {
18
+ const dirPath = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].join(cwd, TEMP_DTS_DIR, name);
19
19
  if (__WEBPACK_EXTERNAL_MODULE_node_fs__["default"].existsSync(dirPath)) return dirPath;
20
20
  __WEBPACK_EXTERNAL_MODULE_node_fs__["default"].mkdirSync(dirPath, {
21
21
  recursive: true
@@ -24,6 +24,25 @@ function ensureTempDeclarationDir(cwd) {
24
24
  __WEBPACK_EXTERNAL_MODULE_node_fs__["default"].writeFileSync(gitIgnorePath, '**/*\n');
25
25
  return dirPath;
26
26
  }
27
+ async function pathExists(path) {
28
+ return __WEBPACK_EXTERNAL_MODULE_node_fs__["default"].promises.access(path).then(()=>true).catch(()=>false);
29
+ }
30
+ async function emptyDir(dir) {
31
+ if (!await pathExists(dir)) return;
32
+ try {
33
+ for (const file of (await __WEBPACK_EXTERNAL_MODULE_node_fs__["default"].promises.readdir(dir)))await __WEBPACK_EXTERNAL_MODULE_node_fs__["default"].promises.rm(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(dir, file), {
34
+ recursive: true,
35
+ force: true
36
+ });
37
+ } catch (err) {
38
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.debug(`Failed to empty dir: ${dir}`);
39
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.logger.debug(err);
40
+ }
41
+ }
42
+ async function clearTempDeclarationDir(cwd) {
43
+ const dirPath = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].join(cwd, TEMP_DTS_DIR);
44
+ await emptyDir(dirPath);
45
+ }
27
46
  function getFileLoc(diagnostic, configPath) {
28
47
  if (diagnostic.file) {
29
48
  const { line, character } = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
@@ -104,4 +123,27 @@ async function calcLongestCommonPath(absPaths) {
104
123
  if (stats?.isFile()) lca = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(lca);
105
124
  return lca;
106
125
  }
107
- export { TEMP_DTS_DIR, TEMP_FOLDER, addBannerAndFooter, calcLongestCommonPath, ensureTempDeclarationDir, getFileLoc, getTimeCost, loadTsconfig, prettyTime, processDtsFiles, processSourceEntry };
126
+ async function cleanDtsFiles(dir) {
127
+ const patterns = [
128
+ '/**/*.d.ts',
129
+ '/**/*.d.cts',
130
+ '/**/*.d.mts'
131
+ ];
132
+ const files = await Promise.all(patterns.map((pattern)=>(0, __WEBPACK_EXTERNAL_MODULE_tinyglobby__.glob)(convertPath((0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(dir, pattern)), {
133
+ absolute: true
134
+ })));
135
+ const allFiles = files.flat();
136
+ await Promise.all(allFiles.map((file)=>__WEBPACK_EXTERNAL_MODULE_node_fs_promises__["default"].rm(file, {
137
+ force: true
138
+ })));
139
+ }
140
+ async function cleanTsBuildInfoFile(tsconfigPath, tsConfigResult) {
141
+ const tsconfigDir = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(tsconfigPath);
142
+ const { outDir, rootDir, tsBuildInfoFile } = tsConfigResult.options;
143
+ let tsbuildInfoFilePath = `${(0, __WEBPACK_EXTERNAL_MODULE_node_path__.basename)(tsconfigPath, '.json')}${tsBuildInfoFile ?? '.tsbuildinfo'}`;
144
+ if (outDir) tsbuildInfoFilePath = rootDir ? (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(outDir, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.relative)((0, __WEBPACK_EXTERNAL_MODULE_node_path__.resolve)(tsconfigDir, rootDir), tsconfigDir), tsbuildInfoFilePath) : (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(outDir, tsbuildInfoFilePath);
145
+ await __WEBPACK_EXTERNAL_MODULE_node_fs_promises__["default"].rm(tsbuildInfoFilePath, {
146
+ force: true
147
+ });
148
+ }
149
+ export { TEMP_DTS_DIR, TEMP_FOLDER, addBannerAndFooter, calcLongestCommonPath, cleanDtsFiles, cleanTsBuildInfoFile, clearTempDeclarationDir, emptyDir, ensureTempDeclarationDir, getFileLoc, getTimeCost, loadTsconfig, pathExists, prettyTime, processDtsFiles, processSourceEntry };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsbuild-plugin-dts",
3
- "version": "0.0.18",
3
+ "version": "0.1.1",
4
4
  "description": "Rsbuild plugin that supports emitting declaration files for TypeScript.",
5
5
  "homepage": "https://lib.rsbuild.dev",
6
6
  "bugs": {
@@ -25,14 +25,14 @@
25
25
  "dist"
26
26
  ],
27
27
  "dependencies": {
28
- "magic-string": "^0.30.12",
28
+ "magic-string": "^0.30.14",
29
29
  "picocolors": "1.1.1",
30
30
  "tinyglobby": "^0.2.10"
31
31
  },
32
32
  "devDependencies": {
33
- "@microsoft/api-extractor": "^7.47.11",
34
- "@rsbuild/core": "~1.1.0",
35
- "rslib": "npm:@rslib/core@0.0.17",
33
+ "@microsoft/api-extractor": "^7.48.0",
34
+ "@rsbuild/core": "~1.1.6",
35
+ "rslib": "npm:@rslib/core@0.1.0",
36
36
  "typescript": "^5.6.3",
37
37
  "@rslib/tsconfig": "0.0.1"
38
38
  },