Skip to content

Commit d16af1d

Browse files
authored
feat: support DTS redirect (#742)
1 parent 36dea47 commit d16af1d

File tree

25 files changed

+1025
-90
lines changed

25 files changed

+1025
-90
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`, Rslib will redirect the import path in the DTS output file to the corresponding relative path based on the [compilerOptions.paths](https://typescriptlang.org/tsconfig#paths) configured in `tsconfig.json`.
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

+6
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
129129
userExternals,
130130
banner,
131131
footer,
132+
redirect = {
133+
path: true,
134+
extension: false,
135+
},
132136
} = data;
133137
logger.start(`Generating DTS... ${color.gray(`(${name})`)}`);
134138

@@ -252,6 +256,8 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
252256
tsConfigResult,
253257
declarationDir,
254258
dtsExtension,
259+
redirect,
260+
rootDir,
255261
banner,
256262
footer,
257263
},

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,6 +11,8 @@ export type EmitDtsOptions = {
1011
tsConfigResult: ts.ParsedCommandLine;
1112
declarationDir: string;
1213
dtsExtension: string;
14+
rootDir: string;
15+
redirect: DtsRedirect;
1316
banner?: string;
1417
footer?: string;
1518
};
@@ -21,6 +24,8 @@ async function handleDiagnosticsAndProcessFiles(
2124
bundle: boolean,
2225
declarationDir: string,
2326
dtsExtension: string,
27+
redirect: DtsRedirect,
28+
rootDir: string,
2429
banner?: string,
2530
footer?: string,
2631
name?: 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+
redirect,
49+
configPath,
50+
rootDir,
51+
banner,
52+
footer,
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,6 +147,9 @@ export async function emitDts(
131147
bundle,
132148
declarationDir,
133149
dtsExtension,
150+
redirect,
151+
configPath,
152+
rootDir,
134153
banner,
135154
footer,
136155
);
@@ -143,6 +162,9 @@ export async function emitDts(
143162
bundle,
144163
declarationDir,
145164
dtsExtension,
165+
redirect,
166+
configPath,
167+
rootDir,
146168
banner,
147169
footer,
148170
);
@@ -179,6 +201,8 @@ export async function emitDts(
179201
bundle,
180202
declarationDir,
181203
dtsExtension,
204+
redirect,
205+
rootDir,
182206
banner,
183207
footer,
184208
name,
@@ -211,6 +235,8 @@ export async function emitDts(
211235
bundle,
212236
declarationDir,
213237
dtsExtension,
238+
redirect,
239+
rootDir,
214240
banner,
215241
footer,
216242
name,
@@ -243,6 +269,9 @@ export async function emitDts(
243269
bundle,
244270
declarationDir,
245271
dtsExtension,
272+
redirect,
273+
configPath,
274+
rootDir,
246275
banner,
247276
footer,
248277
);

0 commit comments

Comments
 (0)