Skip to content

Commit c315d41

Browse files
committed
feat: support DTS redirect
1 parent 36dea47 commit c315d41

File tree

22 files changed

+978
-79
lines changed

22 files changed

+978
-79
lines changed

packages/core/src/config.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ const composeDtsConfig = async (
12171217
libConfig: LibConfig,
12181218
dtsExtension: string,
12191219
): Promise<EnvironmentConfig> => {
1220-
const { format, autoExternal, banner, footer } = libConfig;
1220+
const { format, autoExternal, banner, footer, redirect } = libConfig;
12211221

12221222
let { dts } = libConfig;
12231223

@@ -1243,6 +1243,7 @@ const composeDtsConfig = async (
12431243
autoExternal: getAutoExternalDefaultValue(format!, autoExternal),
12441244
banner: banner?.dts,
12451245
footer: footer?.dts,
1246+
redirect: redirect?.dts,
12461247
}),
12471248
],
12481249
};

packages/core/src/types/config.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,16 @@ export type StyleRedirect = {
177177
extension?: boolean;
178178
};
179179

180-
// @ts-expect-error TODO: support dts redirect in the future
181-
type DtsRedirect = {
180+
export type DtsRedirect = {
181+
/**
182+
* Whether to automatically redirect the import paths of Typescript declaration output files.
183+
* @defaultValue `true`
184+
*/
182185
path?: boolean;
186+
/**
187+
* Whether to automatically redirect the file extension to import paths based on the Typescript declaration output files.
188+
* @defaultValue `false`
189+
*/
183190
extension?: boolean;
184191
};
185192

@@ -190,7 +197,8 @@ export type Redirect = {
190197
style?: StyleRedirect;
191198
/** Controls the redirect of the import paths of output asset files. */
192199
asset?: boolean;
193-
// dts?: DtsRedirect;
200+
/** Controls the redirect of the import paths of output Typescript declaration files. */
201+
dts?: DtsRedirect;
194202
};
195203

196204
export interface LibConfig extends EnvironmentConfig {

packages/plugin-dts/README.md

+71
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,77 @@ pluginDts({
163163
});
164164
```
165165

166+
### redirect
167+
168+
- **Type:**
169+
170+
```ts
171+
type DtsRedirect = {
172+
path?: boolean;
173+
extension?: boolean;
174+
};
175+
```
176+
177+
- **Default:**
178+
179+
```ts
180+
const defaultRedirect = {
181+
path: true,
182+
extension: false,
183+
};
184+
```
185+
186+
Controls the redirect of the import paths of output Typescript declaration files.
187+
188+
```js
189+
pluginDts({
190+
redirect: {
191+
path: true,
192+
extension: false,
193+
},
194+
});
195+
```
196+
197+
#### redirect.path
198+
199+
- **Type:** `boolean`
200+
- **Default:** `true`
201+
202+
Whether to automatically redirect the import paths of Typescript declaration output files.
203+
204+
- When set to `true`, the [compilerOptions.paths](https://typescriptlang.org/tsconfig#paths) configured in the `tsconfig.json` file will take effect, and the import path of the DTS output file will be redirected to the corresponding relative path.
205+
206+
```ts
207+
// `compilerOptions.paths` is set to `{ "@/*": ["src/*"] }`
208+
import { foo } from '@/foo'; // source code of './src/bar.ts' ↓
209+
import { foo } from './foo'; // expected output of './dist/bar.d.ts'
210+
211+
import { foo } from '@/foo'; // source code of './src/utils/index.ts' ↓
212+
import { foo } from '../foo'; // expected output './dist/utils/index.d.ts'
213+
```
214+
215+
- When set to `false`, the original import path will remain unchanged.
216+
217+
#### redirect.extension
218+
219+
- **Type:** `boolean`
220+
- **Default:** `false`
221+
222+
Whether to automatically redirect the file extension to import paths based on the Typescript declaration output files.
223+
224+
- When set to `true`, the import paths in DTS files will be redirected to the corresponding JavaScript extension which can be resolved to corresponding DTS file. The extension of the DTS output file is related to the `dtsExtension` configuration.
225+
226+
```ts
227+
// `dtsExtension` is set to `.d.mts`
228+
import { foo } from './foo'; // source code of './src/bar.ts' ↓
229+
import { foo } from './foo.mjs'; // expected output of './dist/bar.d.mts'
230+
231+
import { foo } from './foo.ts'; // source code of './src/utils/index.ts' ↓
232+
import { foo } from './foo.mjs'; // expected output './dist/utils/index.d.mts'
233+
```
234+
235+
- When set to `false`, the file extension will remain unchanged from the original import path in the rewritten import path of the output file (regardless of whether it is specified or specified as any value).
236+
166237
## Contributing
167238

168239
Please read the [Contributing Guide](https://github.com/web-infra-dev/rslib/blob/main/CONTRIBUTING.md).

packages/plugin-dts/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929
"dev": "rslib build --watch"
3030
},
3131
"dependencies": {
32+
"@ast-grep/napi": "^0.34.4",
3233
"magic-string": "^0.30.17",
3334
"picocolors": "1.1.1",
34-
"tinyglobby": "^0.2.10"
35+
"tinyglobby": "^0.2.10",
36+
"tsconfig-paths": "^4.2.0"
3537
},
3638
"devDependencies": {
3739
"@microsoft/api-extractor": "^7.49.2",

packages/plugin-dts/src/dts.ts

+3
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
129129
userExternals,
130130
banner,
131131
footer,
132+
redirect,
132133
} = data;
133134
logger.start(`Generating DTS... ${color.gray(`(${name})`)}`);
134135

@@ -252,8 +253,10 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
252253
tsConfigResult,
253254
declarationDir,
254255
dtsExtension,
256+
rootDir,
255257
banner,
256258
footer,
259+
redirect,
257260
},
258261
onComplete,
259262
bundle,

packages/plugin-dts/src/index.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import { loadTsconfig, processSourceEntry } from './utils';
99
const __filename = fileURLToPath(import.meta.url);
1010
const __dirname = dirname(__filename);
1111

12+
export type DtsRedirect = {
13+
path?: boolean;
14+
extension?: boolean;
15+
};
16+
1217
export type PluginDtsOptions = {
1318
bundle?: boolean;
1419
distPath?: string;
@@ -24,6 +29,7 @@ export type PluginDtsOptions = {
2429
};
2530
banner?: string;
2631
footer?: string;
32+
redirect?: DtsRedirect;
2733
};
2834

2935
export type DtsEntry = {
@@ -53,14 +59,16 @@ export const PLUGIN_DTS_NAME = 'rsbuild:dts';
5359

5460
// use ts compiler API to generate bundleless dts
5561
// use ts compiler API and api-extractor to generate dts bundle
56-
// TODO: deal alias in dts
5762
export const pluginDts = (options: PluginDtsOptions = {}): RsbuildPlugin => ({
5863
name: PLUGIN_DTS_NAME,
5964

6065
setup(api) {
6166
options.bundle = options.bundle ?? false;
6267
options.abortOnError = options.abortOnError ?? true;
6368
options.build = options.build ?? false;
69+
options.redirect = options.redirect ?? {};
70+
options.redirect.path = options.redirect.path ?? true;
71+
options.redirect.extension = options.redirect.extension ?? false;
6472

6573
const dtsPromises: Promise<TaskResult>[] = [];
6674
let promisesResult: TaskResult[] = [];

packages/plugin-dts/src/tsc.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { logger } from '@rsbuild/core';
22
import color from 'picocolors';
33
import ts from 'typescript';
4+
import type { DtsRedirect } from './index';
45
import { getFileLoc, getTimeCost, processDtsFiles } from './utils';
56

67
export type EmitDtsOptions = {
@@ -10,8 +11,10 @@ export type EmitDtsOptions = {
1011
tsConfigResult: ts.ParsedCommandLine;
1112
declarationDir: string;
1213
dtsExtension: string;
14+
rootDir: string;
1315
banner?: string;
1416
footer?: string;
17+
redirect?: DtsRedirect;
1518
};
1619

1720
async function handleDiagnosticsAndProcessFiles(
@@ -21,8 +24,10 @@ async function handleDiagnosticsAndProcessFiles(
2124
bundle: boolean,
2225
declarationDir: string,
2326
dtsExtension: string,
27+
rootDir: string,
2428
banner?: string,
2529
footer?: string,
30+
redirect?: DtsRedirect,
2631
name?: string,
2732
): Promise<void> {
2833
const diagnosticMessages: string[] = [];
@@ -36,7 +41,16 @@ async function handleDiagnosticsAndProcessFiles(
3641
diagnosticMessages.push(message);
3742
}
3843

39-
await processDtsFiles(bundle, declarationDir, dtsExtension, banner, footer);
44+
await processDtsFiles(
45+
bundle,
46+
declarationDir,
47+
dtsExtension,
48+
configPath,
49+
rootDir,
50+
banner,
51+
footer,
52+
redirect,
53+
);
4054

4155
if (diagnosticMessages.length) {
4256
logger.error(
@@ -65,8 +79,10 @@ export async function emitDts(
6579
declarationDir,
6680
name,
6781
dtsExtension,
82+
rootDir,
6883
banner,
6984
footer,
85+
redirect,
7086
} = options;
7187
const {
7288
options: rawCompilerOptions,
@@ -131,8 +147,11 @@ export async function emitDts(
131147
bundle,
132148
declarationDir,
133149
dtsExtension,
150+
configPath,
151+
rootDir,
134152
banner,
135153
footer,
154+
redirect,
136155
);
137156
}
138157

@@ -143,8 +162,11 @@ export async function emitDts(
143162
bundle,
144163
declarationDir,
145164
dtsExtension,
165+
configPath,
166+
rootDir,
146167
banner,
147168
footer,
169+
redirect,
148170
);
149171
}
150172
};
@@ -179,8 +201,10 @@ export async function emitDts(
179201
bundle,
180202
declarationDir,
181203
dtsExtension,
204+
rootDir,
182205
banner,
183206
footer,
207+
redirect,
184208
name,
185209
);
186210
} else if (!build && compilerOptions.composite) {
@@ -211,8 +235,10 @@ export async function emitDts(
211235
bundle,
212236
declarationDir,
213237
dtsExtension,
238+
rootDir,
214239
banner,
215240
footer,
241+
redirect,
216242
name,
217243
);
218244
} else {
@@ -243,8 +269,11 @@ export async function emitDts(
243269
bundle,
244270
declarationDir,
245271
dtsExtension,
272+
configPath,
273+
rootDir,
246274
banner,
247275
footer,
276+
redirect,
248277
);
249278

250279
if (errorNumber > 0) {

0 commit comments

Comments
 (0)