rsbuild-plugin-dts 0.4.0 → 0.5.0-alpha.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
@@ -163,6 +163,77 @@ pluginDts({
163
163
  });
164
164
  ```
165
165
 
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
+
166
237
  ## Contributing
167
238
 
168
239
  Please read the [Contributing Guide](https://github.com/web-infra-dev/rslib/blob/main/CONTRIBUTING.md).
package/dist/dts.js CHANGED
@@ -52,13 +52,12 @@ const calcBundledPackages = (options)=>{
52
52
  return Array.from(new Set(bundledPackages));
53
53
  };
54
54
  async function generateDts(data) {
55
- const { bundle, dtsEntry, tsconfigPath, tsConfigResult, distPath, rootDistPath, cleanDistPath, name, cwd, build, isWatch, dtsExtension = '.d.ts', autoExternal = true, userExternals, banner, footer } = data;
55
+ const { bundle, dtsEntry, dtsEmitPath, tsconfigPath, tsConfigResult, name, cwd, build, isWatch, dtsExtension = '.d.ts', autoExternal = true, userExternals, banner, footer, redirect = {
56
+ path: true,
57
+ extension: false
58
+ } } = data;
56
59
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.start(`Generating DTS... ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
57
60
  const { options: rawCompilerOptions, fileNames } = tsConfigResult;
58
- const dtsEmitPath = distPath ?? rawCompilerOptions.declarationDir ?? rootDistPath;
59
- if (false !== cleanDistPath) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.cleanDtsFiles)(dtsEmitPath);
60
- if (bundle) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.clearTempDeclarationDir)(cwd);
61
- if (rawCompilerOptions.composite || rawCompilerOptions.incremental || build) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.cleanTsBuildInfoFile)(tsconfigPath, rawCompilerOptions);
62
61
  const rootDir = rawCompilerOptions.rootDir ?? (rawCompilerOptions.composite ? (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname)(tsconfigPath) : await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.calcLongestCommonPath)(fileNames.filter((fileName)=>!/\.d\.(ts|mts|cts)$/.test(fileName)))) ?? (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname)(tsconfigPath);
63
62
  const resolvedDtsEmitPath = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.normalize)((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname)(tsconfigPath), dtsEmitPath));
64
63
  if (build) {
@@ -109,6 +108,8 @@ async function generateDts(data) {
109
108
  tsConfigResult,
110
109
  declarationDir,
111
110
  dtsExtension,
111
+ redirect,
112
+ rootDir,
112
113
  banner,
113
114
  footer
114
115
  }, onComplete, bundle, isWatch, build);
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { type RsbuildConfig, type RsbuildPlugin } from '@rsbuild/core';
2
2
  import ts from 'typescript';
3
+ export type DtsRedirect = {
4
+ path?: boolean;
5
+ extension?: boolean;
6
+ };
3
7
  export type PluginDtsOptions = {
4
8
  bundle?: boolean;
5
9
  distPath?: string;
@@ -13,6 +17,7 @@ export type PluginDtsOptions = {
13
17
  };
14
18
  banner?: string;
15
19
  footer?: string;
20
+ redirect?: DtsRedirect;
16
21
  };
17
22
  export type DtsEntry = {
18
23
  name?: string;
@@ -23,11 +28,10 @@ export type DtsGenOptions = PluginDtsOptions & {
23
28
  cwd: string;
24
29
  isWatch: boolean;
25
30
  dtsEntry: DtsEntry;
31
+ dtsEmitPath: string;
26
32
  build?: boolean;
27
33
  tsconfigPath: string;
28
34
  tsConfigResult: ts.ParsedCommandLine;
29
- rootDistPath: string;
30
- cleanDistPath: NonNullable<RsbuildConfig['output']>['cleanDistPath'];
31
35
  userExternals?: NonNullable<RsbuildConfig['output']>['externals'];
32
36
  };
33
37
  export declare const PLUGIN_DTS_NAME = "rsbuild:dts";
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:c
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__ from "node:url";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__ from "@rsbuild/core";
5
+ import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
5
6
  import * as __WEBPACK_EXTERNAL_MODULE_typescript__ from "typescript";
6
7
  import * as __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__ from "./utils.js";
7
8
  const src_rslib_entry_filename = (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.fileURLToPath)(import.meta.url);
@@ -13,6 +14,9 @@ const pluginDts = (options = {})=>({
13
14
  options.bundle = options.bundle ?? false;
14
15
  options.abortOnError = options.abortOnError ?? true;
15
16
  options.build = options.build ?? false;
17
+ options.redirect = options.redirect ?? {};
18
+ options.redirect.path = options.redirect.path ?? true;
19
+ options.redirect.extension = options.redirect.extension ?? false;
16
20
  const dtsPromises = [];
17
21
  let promisesResult = [];
18
22
  let childProcesses = [];
@@ -23,10 +27,15 @@ const pluginDts = (options = {})=>({
23
27
  const cwd = api.context.rootPath;
24
28
  const tsconfigPath = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].findConfigFile(cwd, __WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys.fileExists, config.source.tsconfigPath);
25
29
  if (!tsconfigPath) {
26
- __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(`tsconfig.json not found in ${cwd}`);
30
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(`Failed to resolve tsconfig file ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(`"${config.source.tsconfigPath}"`)} from ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(cwd)}. Please ensure that the file exists.`);
27
31
  throw new Error();
28
32
  }
29
33
  const tsConfigResult = (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.loadTsconfig)(tsconfigPath);
34
+ const { options: rawCompilerOptions } = tsConfigResult;
35
+ const dtsEmitPath = options.distPath ?? rawCompilerOptions.declarationDir ?? config.output?.distPath?.root;
36
+ if (false !== config.output.cleanDistPath) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.cleanDtsFiles)(dtsEmitPath);
37
+ if (options.bundle) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.clearTempDeclarationDir)(cwd);
38
+ if (rawCompilerOptions.composite || rawCompilerOptions.incremental || options.build) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.cleanTsBuildInfoFile)(tsconfigPath, rawCompilerOptions);
30
39
  const jsExtension = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.extname)(src_rslib_entry_filename);
31
40
  const childProcess = (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.fork)((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join)(src_rslib_entry_dirname, `./dts${jsExtension}`), [], {
32
41
  stdio: 'inherit'
@@ -35,11 +44,10 @@ const pluginDts = (options = {})=>({
35
44
  const dtsGenOptions = {
36
45
  ...options,
37
46
  dtsEntry,
38
- rootDistPath: config.output?.distPath?.root,
47
+ dtsEmitPath,
39
48
  userExternals: config.output.externals,
40
49
  tsconfigPath,
41
50
  tsConfigResult,
42
- cleanDistPath: config.output.cleanDistPath,
43
51
  name: environment.name,
44
52
  cwd,
45
53
  isWatch
package/dist/tsc.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import ts from 'typescript';
2
+ import type { DtsRedirect } from './index';
2
3
  export type EmitDtsOptions = {
3
4
  name: string;
4
5
  cwd: string;
@@ -6,6 +7,8 @@ export type EmitDtsOptions = {
6
7
  tsConfigResult: ts.ParsedCommandLine;
7
8
  declarationDir: string;
8
9
  dtsExtension: string;
10
+ rootDir: string;
11
+ redirect: DtsRedirect;
9
12
  banner?: string;
10
13
  footer?: string;
11
14
  };
package/dist/tsc.js CHANGED
@@ -2,14 +2,14 @@ import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__ from "@rsbuild/co
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_d88b7fe1__ from "./utils.js";
5
- async function handleDiagnosticsAndProcessFiles(diagnostics, configPath, host, bundle, declarationDir, dtsExtension, banner, footer, name) {
5
+ async function handleDiagnosticsAndProcessFiles(diagnostics, configPath, host, bundle, declarationDir, dtsExtension, redirect, rootDir, banner, footer, name) {
6
6
  const diagnosticMessages = [];
7
7
  for (const diagnostic of diagnostics){
8
8
  const fileLoc = (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.getFileLoc)(diagnostic, configPath);
9
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
10
  diagnosticMessages.push(message);
11
11
  }
12
- await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
12
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, redirect, configPath, rootDir, banner, footer);
13
13
  if (diagnosticMessages.length) {
14
14
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(`Failed to emit declaration files. ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
15
15
  for (const message of diagnosticMessages)__WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(message);
@@ -18,7 +18,7 @@ async function handleDiagnosticsAndProcessFiles(diagnostics, configPath, host, b
18
18
  }
19
19
  async function emitDts(options, onComplete, bundle = false, isWatch = false, build = false) {
20
20
  const start = Date.now();
21
- const { configPath, tsConfigResult, declarationDir, name, dtsExtension, banner, footer } = options;
21
+ const { configPath, tsConfigResult, declarationDir, name, dtsExtension, rootDir, banner, footer, redirect } = options;
22
22
  const { options: rawCompilerOptions, fileNames, projectReferences } = tsConfigResult;
23
23
  const compilerOptions = {
24
24
  ...rawCompilerOptions,
@@ -47,11 +47,11 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
47
47
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.info(message);
48
48
  onComplete(true);
49
49
  }
50
- await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
50
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, redirect, configPath, rootDir, banner, footer);
51
51
  }
52
52
  if (6193 === diagnostic.code) {
53
53
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(message);
54
- await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
54
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, redirect, configPath, rootDir, banner, footer);
55
55
  }
56
56
  };
57
57
  const system = {
@@ -84,7 +84,7 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
84
84
  });
85
85
  program.emit();
86
86
  const allDiagnostics = program.getSemanticDiagnostics().concat(program.getConfigFileParsingDiagnostics());
87
- await handleDiagnosticsAndProcessFiles(allDiagnostics, configPath, host, bundle, declarationDir, dtsExtension, banner, footer, name);
87
+ await handleDiagnosticsAndProcessFiles(allDiagnostics, configPath, host, bundle, declarationDir, dtsExtension, redirect, rootDir, banner, footer, name);
88
88
  } else {
89
89
  let errorNumber = 0;
90
90
  const reportErrorSummary = (errorCount)=>{
@@ -95,7 +95,7 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
95
95
  configPath
96
96
  ], compilerOptions);
97
97
  solutionBuilder.build();
98
- await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, banner, footer);
98
+ await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processDtsFiles)(bundle, declarationDir, dtsExtension, redirect, configPath, rootDir, banner, footer);
99
99
  if (errorNumber > 0) {
100
100
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(`Failed to emit declaration files. ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
101
101
  throw new Error('DTS generation failed');
@@ -112,7 +112,7 @@ async function emitDts(options, onComplete, bundle = false, isWatch = false, bui
112
112
  });
113
113
  const emitResult = program.emit();
114
114
  const allDiagnostics = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
115
- await handleDiagnosticsAndProcessFiles(allDiagnostics, configPath, host, bundle, declarationDir, dtsExtension, banner, footer, name);
115
+ await handleDiagnosticsAndProcessFiles(allDiagnostics, configPath, host, bundle, declarationDir, dtsExtension, redirect, rootDir, banner, footer, name);
116
116
  }
117
117
  __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.ready(`DTS generated in ${(0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.getTimeCost)(start)} ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].gray(`(${name})`)}`);
118
118
  }
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { type RsbuildConfig } from '@rsbuild/core';
2
+ import { type MatchPath } from 'tsconfig-paths';
2
3
  import ts from 'typescript';
3
- import type { DtsEntry } from './index';
4
+ import type { DtsEntry, DtsRedirect } from './index';
5
+ export declare const JS_EXTENSIONS_PATTERN: RegExp;
4
6
  export declare function loadTsconfig(tsconfigPath: string): ts.ParsedCommandLine;
5
7
  export declare const TEMP_FOLDER = ".rslib";
6
8
  export declare const TEMP_DTS_DIR: string;
@@ -11,8 +13,9 @@ export declare function clearTempDeclarationDir(cwd: string): Promise<void>;
11
13
  export declare function getFileLoc(diagnostic: ts.Diagnostic, configPath: string): string;
12
14
  export declare const prettyTime: (seconds: number) => string;
13
15
  export declare function getTimeCost(start: number): string;
14
- export declare function addBannerAndFooter(file: string, banner?: string, footer?: string): Promise<void>;
15
- export declare function processDtsFiles(bundle: boolean, dir: string, dtsExtension: string, banner?: string, footer?: string): Promise<void>;
16
+ export declare function addBannerAndFooter(dtsFile: string, banner?: string, footer?: string): Promise<void>;
17
+ export declare function redirectDtsImports(dtsFile: string, dtsExtension: string, redirect: DtsRedirect, matchPath: MatchPath, outDir: string, rootDir: string): Promise<void>;
18
+ export declare function processDtsFiles(bundle: boolean, dir: string, dtsExtension: string, redirect: DtsRedirect, tsconfigPath: string, rootDir: string, banner?: string, footer?: string): Promise<void>;
16
19
  export declare function processSourceEntry(bundle: boolean, entryConfig: NonNullable<RsbuildConfig['source']>['entry']): DtsEntry;
17
20
  export declare function calcLongestCommonPath(absPaths: string[]): Promise<string | null>;
18
21
  export declare function cleanDtsFiles(dir: string): Promise<void>;
package/dist/utils.js CHANGED
@@ -2,11 +2,28 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__ from "node:fs/promises";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE_node_os_74b4b876__ from "node:os";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
5
+ import * as __WEBPACK_EXTERNAL_MODULE__ast_grep_napi_5dd5d9b1__ from "@ast-grep/napi";
5
6
  import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__ from "@rsbuild/core";
6
7
  import * as __WEBPACK_EXTERNAL_MODULE_magic_string_758c1a52__ from "magic-string";
7
8
  import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
8
9
  import * as __WEBPACK_EXTERNAL_MODULE_tinyglobby__ from "tinyglobby";
10
+ import * as __WEBPACK_EXTERNAL_MODULE_tsconfig_paths_df62e9eb__ from "tsconfig-paths";
9
11
  import * as __WEBPACK_EXTERNAL_MODULE_typescript__ from "typescript";
12
+ const JS_EXTENSIONS = [
13
+ 'js',
14
+ 'mjs',
15
+ 'jsx',
16
+ '(?<!\\.d\\.)ts',
17
+ '(?<!\\.d\\.)mts',
18
+ '(?<!\\.d\\.)cts',
19
+ 'tsx',
20
+ 'cjs',
21
+ 'cjsx',
22
+ 'mjsx',
23
+ 'mtsx',
24
+ 'ctsx'
25
+ ];
26
+ const JS_EXTENSIONS_PATTERN = new RegExp(`\\.(${JS_EXTENSIONS.join('|')})$`);
10
27
  function loadTsconfig(tsconfigPath) {
11
28
  const configFile = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].readConfigFile(tsconfigPath, __WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys.readFile);
12
29
  const configFileContent = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].parseJsonConfigFileContent(configFile.config, __WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(tsconfigPath));
@@ -68,21 +85,124 @@ function getTimeCost(start) {
68
85
  const second = (Date.now() - start) / 1000;
69
86
  return prettyTime(second);
70
87
  }
71
- async function addBannerAndFooter(file, banner, footer) {
72
- if (!banner && !footer) return;
73
- const content = await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].readFile(file, 'utf-8');
88
+ async function addBannerAndFooter(dtsFile, banner, footer) {
89
+ const content = await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].readFile(dtsFile, 'utf-8');
74
90
  const code = new __WEBPACK_EXTERNAL_MODULE_magic_string_758c1a52__["default"](content);
75
91
  if (banner && !content.trimStart().startsWith(banner.trim())) code.prepend(`${banner}\n`);
76
92
  if (footer && !content.trimEnd().endsWith(footer.trim())) code.append(`\n${footer}\n`);
77
- if (code.hasChanged()) await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(file, code.toString());
93
+ if (code.hasChanged()) await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(dtsFile, code.toString());
78
94
  }
79
- async function processDtsFiles(bundle, dir, dtsExtension, banner, footer) {
95
+ async function redirectDtsImports(dtsFile, dtsExtension, redirect, matchPath, outDir, rootDir) {
96
+ const content = await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].readFile(dtsFile, 'utf-8');
97
+ const code = new __WEBPACK_EXTERNAL_MODULE_magic_string_758c1a52__["default"](content);
98
+ const sgNode = (await (0, __WEBPACK_EXTERNAL_MODULE__ast_grep_napi_5dd5d9b1__.parseAsync)("typescript", content)).root();
99
+ const matcher = {
100
+ rule: {
101
+ kind: 'string_fragment',
102
+ any: [
103
+ {
104
+ inside: {
105
+ stopBy: 'end',
106
+ kind: 'import_statement',
107
+ field: 'source'
108
+ }
109
+ },
110
+ {
111
+ inside: {
112
+ stopBy: 'end',
113
+ kind: 'export_statement',
114
+ field: 'source'
115
+ }
116
+ },
117
+ {
118
+ inside: {
119
+ kind: 'string',
120
+ inside: {
121
+ kind: 'arguments',
122
+ inside: {
123
+ kind: 'call_expression',
124
+ has: {
125
+ field: 'function',
126
+ regex: '^(import|require)$'
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ ]
133
+ }
134
+ };
135
+ const matchModule = sgNode.findAll(matcher).map((matchNode)=>({
136
+ n: matchNode.text(),
137
+ s: matchNode.range().start.index,
138
+ e: matchNode.range().end.index
139
+ }));
140
+ const extensions = dtsExtension.replace(/\.d\.ts$/, '.js').replace(/\.d\.cts$/, '.cjs').replace(/\.d\.mts$/, '.mjs');
141
+ for (const imp of matchModule){
142
+ const { n: importPath, s: start, e: end } = imp;
143
+ if (!!importPath) try {
144
+ const absoluteImportPath = matchPath(importPath, void 0, void 0, [
145
+ '.jsx',
146
+ '.tsx',
147
+ '.js',
148
+ '.ts',
149
+ '.mjs',
150
+ '.mts',
151
+ '.cjs',
152
+ '.cts'
153
+ ]);
154
+ let redirectImportPath = importPath;
155
+ if (absoluteImportPath && redirect.path) {
156
+ const isOutsideRootdir = !(0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.normalize)(absoluteImportPath).startsWith((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.normalize)(rootDir) + __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep);
157
+ if (isOutsideRootdir) {
158
+ const relativePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative)((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname)(dtsFile), absoluteImportPath);
159
+ redirectImportPath = relativePath.startsWith('..') ? relativePath : `./${relativePath}`;
160
+ } else {
161
+ const originalFilePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)(rootDir, (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative)(outDir, dtsFile));
162
+ const originalSourceDir = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname)(originalFilePath);
163
+ const relativePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative)(originalSourceDir, absoluteImportPath);
164
+ redirectImportPath = relativePath.startsWith('..') ? relativePath : `./${relativePath}`;
165
+ }
166
+ }
167
+ const ext = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.extname)(redirectImportPath);
168
+ if (ext) {
169
+ if (JS_EXTENSIONS_PATTERN.test(redirectImportPath)) {
170
+ if (redirect.extension) redirectImportPath = redirectImportPath.replace(/\.[^.]+$/, extensions);
171
+ }
172
+ } else {
173
+ if (absoluteImportPath && (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.normalize)(absoluteImportPath).startsWith((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.normalize)(rootDir))) {
174
+ if (redirect.extension) redirectImportPath = `${redirectImportPath}${extensions}`;
175
+ }
176
+ if (!absoluteImportPath && importPath.startsWith('.')) {
177
+ if (redirect.extension) redirectImportPath = `${redirectImportPath}${extensions}`;
178
+ }
179
+ }
180
+ const normalizedRedirectImportPath = redirectImportPath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
181
+ code.overwrite(start, end, normalizedRedirectImportPath);
182
+ } catch (err) {
183
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.debug(err);
184
+ }
185
+ }
186
+ if (code.hasChanged()) await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(dtsFile, code.toString());
187
+ }
188
+ async function processDtsFiles(bundle, dir, dtsExtension, redirect, tsconfigPath, rootDir, banner, footer) {
80
189
  if (bundle) return;
190
+ let matchPath;
191
+ if (redirect.path || redirect.extension) {
192
+ const result = (0, __WEBPACK_EXTERNAL_MODULE_tsconfig_paths_df62e9eb__.loadConfig)(tsconfigPath);
193
+ if ('failed' === result.resultType) {
194
+ __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(result.message);
195
+ return;
196
+ }
197
+ const { absoluteBaseUrl, paths, mainFields, addMatchAll } = result;
198
+ matchPath = (0, __WEBPACK_EXTERNAL_MODULE_tsconfig_paths_df62e9eb__.createMatchPath)(absoluteBaseUrl, paths, mainFields, addMatchAll);
199
+ }
81
200
  const dtsFiles = await (0, __WEBPACK_EXTERNAL_MODULE_tinyglobby__.glob)(convertPath((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join)(dir, '/**/*.d.ts')), {
82
201
  absolute: true
83
202
  });
84
203
  for (const file of dtsFiles)try {
85
- await addBannerAndFooter(file, banner, footer);
204
+ if (banner || footer) await addBannerAndFooter(file, banner, footer);
205
+ if ((redirect.path || redirect.extension) && matchPath) await redirectDtsImports(file, dtsExtension, redirect, matchPath, dir, rootDir);
86
206
  const newFile = file.replace('.d.ts', dtsExtension);
87
207
  __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].renameSync(file, newFile);
88
208
  } catch (error) {
@@ -140,4 +260,4 @@ async function cleanTsBuildInfoFile(tsconfigPath, compilerOptions) {
140
260
  force: true
141
261
  });
142
262
  }
143
- export { TEMP_DTS_DIR, TEMP_FOLDER, addBannerAndFooter, calcLongestCommonPath, cleanDtsFiles, cleanTsBuildInfoFile, clearTempDeclarationDir, emptyDir, ensureTempDeclarationDir, getFileLoc, getTimeCost, loadTsconfig, pathExists, prettyTime, processDtsFiles, processSourceEntry };
263
+ export { JS_EXTENSIONS_PATTERN, TEMP_DTS_DIR, TEMP_FOLDER, addBannerAndFooter, calcLongestCommonPath, cleanDtsFiles, cleanTsBuildInfoFile, clearTempDeclarationDir, emptyDir, ensureTempDeclarationDir, getFileLoc, getTimeCost, loadTsconfig, pathExists, prettyTime, processDtsFiles, processSourceEntry, redirectDtsImports };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsbuild-plugin-dts",
3
- "version": "0.4.0",
3
+ "version": "0.5.0-alpha.0",
4
4
  "description": "Rsbuild plugin that supports emitting declaration files for TypeScript.",
5
5
  "homepage": "https://lib.rsbuild.dev",
6
6
  "bugs": {
@@ -25,15 +25,17 @@
25
25
  "dist"
26
26
  ],
27
27
  "dependencies": {
28
+ "@ast-grep/napi": "^0.35.0",
28
29
  "magic-string": "^0.30.17",
29
30
  "picocolors": "1.1.1",
30
- "tinyglobby": "^0.2.10"
31
+ "tinyglobby": "^0.2.10",
32
+ "tsconfig-paths": "^4.2.0"
31
33
  },
32
34
  "devDependencies": {
33
- "@microsoft/api-extractor": "^7.49.1",
34
- "@rsbuild/core": "~1.2.3",
35
- "rsbuild-plugin-publint": "^0.2.1",
36
- "rslib": "npm:@rslib/core@0.3.2",
35
+ "@microsoft/api-extractor": "^7.50.0",
36
+ "@rsbuild/core": "~1.2.8",
37
+ "rsbuild-plugin-publint": "^0.3.0",
38
+ "rslib": "npm:@rslib/core@0.4.1",
37
39
  "typescript": "^5.7.3",
38
40
  "@rslib/tsconfig": "0.0.1"
39
41
  },