Skip to content

Commit 3c0501c

Browse files
authored
feat: support DTS autoExtension (#72)
1 parent 12066db commit 3c0501c

File tree

15 files changed

+194
-39
lines changed

15 files changed

+194
-39
lines changed

e2e/cases/dts/__snapshots__/index.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`dts when bundle: false > basic 1`] = `
3+
exports[`dts when bundle: false > basic 2`] = `
44
{
55
"./dist/esm/index.d.ts": "export * from './utils/numbers';
66
export * from './utils/strings';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper';
2+
import { defineConfig } from '@rslib/core';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig(__dirname, {
7+
bundle: false,
8+
}),
9+
generateBundleCjsConfig(__dirname, {
10+
bundle: false,
11+
dts: {
12+
bundle: false,
13+
},
14+
}),
15+
],
16+
source: {
17+
entry: {
18+
main: ['./src/**'],
19+
},
20+
},
21+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "dts-bundle-false-test",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module"
6+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper';
2+
import { defineConfig } from '@rslib/core';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig(__dirname),
7+
generateBundleCjsConfig(__dirname, {
8+
dts: {
9+
bundle: true,
10+
},
11+
}),
12+
],
13+
source: {
14+
entry: {
15+
main: './src/index.ts',
16+
},
17+
},
18+
});

e2e/cases/dts/index.test.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@ describe('dts when bundle: false', () => {
1111
'dts',
1212
);
1313

14-
expect(files.esm?.length).toBe(4);
15-
expect(files.esm?.[0]!.endsWith('.d.ts')).toEqual(true);
14+
expect(files.esm).toMatchInlineSnapshot(`
15+
[
16+
"./dist/esm/index.d.ts",
17+
"./dist/esm/sum.d.ts",
18+
"./dist/esm/utils/numbers.d.ts",
19+
"./dist/esm/utils/strings.d.ts",
20+
]
21+
`);
1622
expect(contents.esm).toMatchSnapshot();
1723
});
1824

@@ -34,8 +40,15 @@ describe('dts when bundle: false', () => {
3440
'distPath.config.ts',
3541
'dts',
3642
);
37-
expect(files.esm?.length).toBe(4);
38-
expect(files.esm?.[0]!.startsWith('./dist/custom')).toEqual(true);
43+
44+
expect(files.esm).toMatchInlineSnapshot(`
45+
[
46+
"./dist/custom/index.d.ts",
47+
"./dist/custom/sum.d.ts",
48+
"./dist/custom/utils/numbers.d.ts",
49+
"./dist/custom/utils/strings.d.ts",
50+
]
51+
`);
3952
});
4053

4154
test('abortOnError: false', async () => {
@@ -48,6 +61,24 @@ describe('dts when bundle: false', () => {
4861

4962
expect(isSuccess).toBe(true);
5063
});
64+
65+
test('autoExtension: true', async () => {
66+
const fixturePath = join(__dirname, 'bundle-false');
67+
const { files } = await buildAndGetResults(
68+
fixturePath,
69+
'autoExtension.config.ts',
70+
'dts',
71+
);
72+
73+
expect(files.cjs).toMatchInlineSnapshot(`
74+
[
75+
"./dist/cjs/index.d.cts",
76+
"./dist/cjs/sum.d.cts",
77+
"./dist/cjs/utils/numbers.d.cts",
78+
"./dist/cjs/utils/strings.d.cts",
79+
]
80+
`);
81+
});
5182
});
5283

5384
describe('dts when bundle: true', () => {
@@ -59,7 +90,7 @@ describe('dts when bundle: true', () => {
5990
'dts',
6091
);
6192

62-
expect(entryFiles.esm!.endsWith('index.d.ts')).toEqual(true);
93+
expect(entryFiles.esm).toEqual('./dist/esm/index.d.ts');
6394
expect(entries).toMatchSnapshot();
6495
});
6596

@@ -82,7 +113,7 @@ describe('dts when bundle: true', () => {
82113
'dts',
83114
);
84115

85-
expect(entryFiles.esm!.startsWith('./dist/custom')).toEqual(true);
116+
expect(entryFiles.esm).toEqual('./dist/custom/index.d.ts');
86117
});
87118

88119
test('abortOnError: false', async () => {
@@ -95,4 +126,15 @@ describe('dts when bundle: true', () => {
95126

96127
expect(isSuccess).toBe(true);
97128
});
129+
130+
test('autoExtension: true', async () => {
131+
const fixturePath = join(__dirname, 'bundle');
132+
const { entryFiles } = await buildAndGetResults(
133+
fixturePath,
134+
'autoExtension.config.ts',
135+
'dts',
136+
);
137+
138+
expect(entryFiles.cjs).toEqual('./dist/cjs/index.d.cts');
139+
});
98140
});

examples/express-plugin/rslib.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { defineConfig } from '@rslib/core';
22

33
const shared = {
4-
autoExtension: true,
54
dts: {
65
bundle: false,
76
},

examples/react-component/rslib.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { pluginReact } from '@rsbuild/plugin-react';
22
import { defineConfig } from '@rslib/core';
33

44
const shared = {
5-
autoExtension: true,
65
dts: {
76
bundle: false,
87
},

packages/core/src/config.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,19 +168,25 @@ const composeAutoExtensionConfig = (
168168
format: Format,
169169
root: string,
170170
autoExtension: boolean,
171-
): RsbuildConfig => {
172-
const { jsExtension } = getDefaultExtension({
171+
): {
172+
config: RsbuildConfig;
173+
dtsExtension: string;
174+
} => {
175+
const { jsExtension, dtsExtension } = getDefaultExtension({
173176
format,
174177
root,
175178
autoExtension,
176179
});
177180

178181
return {
179-
output: {
180-
filename: {
181-
js: `[name]${jsExtension}`,
182+
config: {
183+
output: {
184+
filename: {
185+
js: `[name]${jsExtension}`,
186+
},
182187
},
183188
},
189+
dtsExtension,
184190
};
185191
};
186192

@@ -325,6 +331,7 @@ const composeBundleConfig = (bundle = true): RsbuildConfig => {
325331

326332
const composeDtsConfig = async (
327333
libConfig: LibConfig,
334+
dtsExtension: string,
328335
): Promise<RsbuildConfig> => {
329336
const { dts, bundle, output } = libConfig;
330337

@@ -337,6 +344,7 @@ const composeDtsConfig = async (
337344
bundle: dts?.bundle ?? bundle,
338345
distPath: dts?.distPath ?? output?.distPath?.root ?? './dist',
339346
abortOnError: dts?.abortOnError ?? true,
347+
dtsExtension,
340348
}),
341349
],
342350
};
@@ -389,11 +397,8 @@ async function composeLibRsbuildConfig(
389397

390398
const { format, autoExtension = true } = config;
391399
const formatConfig = composeFormatConfig(format!);
392-
const autoExtensionConfig = composeAutoExtensionConfig(
393-
format!,
394-
dirname(configPath),
395-
autoExtension,
396-
);
400+
const { config: autoExtensionConfig, dtsExtension } =
401+
composeAutoExtensionConfig(format!, dirname(configPath), autoExtension);
397402
const bundleConfig = composeBundleConfig(config.bundle);
398403
const targetConfig = composeTargetConfig(config.output?.target);
399404
const syntaxConfig = composeSyntaxConfig(
@@ -405,7 +410,7 @@ async function composeLibRsbuildConfig(
405410
config.bundle,
406411
dirname(configPath),
407412
);
408-
const dtsConfig = await composeDtsConfig(config);
413+
const dtsConfig = await composeDtsConfig(config, dtsExtension);
409414

410415
return mergeRsbuildConfig(
411416
formatConfig,

packages/plugin-dts/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"dev": "modern build --watch"
3131
},
3232
"dependencies": {
33+
"fast-glob": "^3.3.2",
3334
"picocolors": "1.0.1"
3435
},
3536
"devDependencies": {

packages/plugin-dts/src/apiExtractor.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,34 @@ import {
55
type ExtractorResult,
66
} from '@microsoft/api-extractor';
77
import { logger } from '@rsbuild/core';
8+
import color from 'picocolors';
9+
import { getTimeCost } from './utils';
810

911
export type BundleOptions = {
12+
name: string;
1013
cwd: string;
1114
outDir: string;
15+
dtsExtension: string;
1216
entry?: string;
1317
tsconfigPath?: string;
1418
};
1519

16-
export function bundleDts(options: BundleOptions): void {
20+
export async function bundleDts(options: BundleOptions): Promise<void> {
1721
const {
22+
name,
1823
cwd,
1924
outDir,
25+
dtsExtension,
2026
entry = 'index.d.ts',
2127
tsconfigPath = 'tsconfig.json',
2228
} = options;
2329
try {
24-
const untrimmedFilePath = join(cwd, relative(cwd, outDir), 'index.d.ts');
30+
const start = Date.now();
31+
const untrimmedFilePath = join(
32+
cwd,
33+
relative(cwd, outDir),
34+
`index${dtsExtension}`,
35+
);
2536
const internalConfig = {
2637
mainEntryPointFilePath: entry,
2738
// TODO: use !externals
@@ -49,11 +60,11 @@ export function bundleDts(options: BundleOptions): void {
4960
});
5061

5162
if (!extractorResult.succeeded) {
52-
throw new Error('API Extractor rollup error');
63+
throw new Error(`API Extractor error. ${color.gray(`(${name})`)}`);
5364
}
5465

5566
logger.info(
56-
`API Extractor writing package typings succeeded: ${untrimmedFilePath}`,
67+
`API Extractor bundle DTS succeeded: ${color.cyan(untrimmedFilePath)} in ${getTimeCost(start)} ${color.gray(`(${name})`)}`,
5768
);
5869
} catch (e) {
5970
logger.error('API Extractor', e);

0 commit comments

Comments
 (0)