Skip to content

Commit ba55822

Browse files
committed
feat: disable autoExternal when format is umd or mf
1 parent 4073e70 commit ba55822

File tree

9 files changed

+111
-9
lines changed

9 files changed

+111
-9
lines changed

packages/core/src/config.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import {
5858
color,
5959
getAbsolutePath,
6060
isEmptyObject,
61+
isIntermediateOutputFormat,
6162
isObject,
6263
nodeBuiltInModules,
6364
omit,
@@ -235,13 +236,14 @@ const composeExternalsWarnConfig = (
235236
};
236237

237238
export const composeAutoExternalConfig = (options: {
238-
autoExternal: AutoExternal;
239+
format: Format;
240+
autoExternal?: AutoExternal;
239241
pkgJson?: PkgJson;
240242
userExternals?: NonNullable<RsbuildConfig['output']>['externals'];
241243
}): RsbuildConfig => {
242-
const { autoExternal, pkgJson, userExternals } = options;
244+
const { format, autoExternal = true, pkgJson, userExternals } = options;
243245

244-
if (!autoExternal) {
246+
if (autoExternal === false || !isIntermediateOutputFormat(format)) {
245247
return {};
246248
}
247249

@@ -1005,7 +1007,7 @@ const composeDtsConfig = async (
10051007
libConfig: LibConfig,
10061008
dtsExtension: string,
10071009
): Promise<RsbuildConfig> => {
1008-
const { autoExternal, banner, footer } = libConfig;
1010+
const { format, autoExternal = true, banner, footer } = libConfig;
10091011

10101012
let { dts } = libConfig;
10111013

@@ -1028,7 +1030,9 @@ const composeDtsConfig = async (
10281030
build: dts?.build,
10291031
abortOnError: dts?.abortOnError,
10301032
dtsExtension: dts?.autoExtension ? dtsExtension : '.d.ts',
1031-
autoExternal,
1033+
autoExternal: !isIntermediateOutputFormat(format!)
1034+
? false
1035+
: autoExternal,
10321036
banner: banner?.dts,
10331037
footer: footer?.dts,
10341038
}),
@@ -1150,7 +1154,7 @@ async function composeLibRsbuildConfig(config: LibConfig) {
11501154
banner = {},
11511155
footer = {},
11521156
autoExtension = true,
1153-
autoExternal = true,
1157+
autoExternal,
11541158
externalHelpers = false,
11551159
redirect = {},
11561160
umdName,
@@ -1190,6 +1194,7 @@ async function composeLibRsbuildConfig(config: LibConfig) {
11901194
);
11911195
const syntaxConfig = composeSyntaxConfig(target, config?.syntax);
11921196
const autoExternalConfig = composeAutoExternalConfig({
1197+
format: format!,
11931198
autoExternal,
11941199
pkgJson,
11951200
userExternals: config.output?.externals,

packages/core/src/types/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export interface LibConfig extends RsbuildConfig {
109109
autoExtension?: boolean;
110110
/**
111111
* Whether to automatically externalize dependencies of different dependency types and do not bundle them.
112+
* Only takes effect when {@link format} is `cjs` or `esm`.
112113
* @defaultValue `true`
113114
* @see {@link https://lib.rsbuild.dev/config/lib/auto-external}
114115
*/

packages/core/src/utils/helper.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path, { isAbsolute, join } from 'node:path';
44
import type { RsbuildPlugins } from '@rsbuild/core';
55
import color from 'picocolors';
66

7-
import type { LibConfig, PkgJson } from '../types';
7+
import type { Format, LibConfig, PkgJson } from '../types';
88
import { logger } from './logger';
99

1010
/**
@@ -232,4 +232,8 @@ export const isTTY = (type: 'stdin' | 'stdout' = 'stdout'): boolean => {
232232
);
233233
};
234234

235+
export const isIntermediateOutputFormat = (format: Format): boolean => {
236+
return format === 'cjs' || format === 'esm';
237+
};
238+
235239
export { color };

packages/core/tests/external.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,86 @@ import { composeAutoExternalConfig } from '../src/config';
44
vi.mock('rslog');
55

66
describe('should composeAutoExternalConfig correctly', () => {
7+
it('autoExternal is undefined', () => {
8+
const esmResult = composeAutoExternalConfig({
9+
format: 'esm',
10+
autoExternal: undefined,
11+
pkgJson: {
12+
name: 'esm',
13+
dependencies: {
14+
foo: '1.0.0',
15+
},
16+
},
17+
});
18+
19+
const cjsResult = composeAutoExternalConfig({
20+
format: 'cjs',
21+
autoExternal: undefined,
22+
pkgJson: {
23+
name: 'cjs',
24+
dependencies: {
25+
foo: '1.0.0',
26+
},
27+
},
28+
});
29+
30+
expect(esmResult).toMatchInlineSnapshot(`
31+
{
32+
"output": {
33+
"externals": [
34+
/\\^foo\\(\\$\\|\\\\/\\|\\\\\\\\\\)/,
35+
"foo",
36+
],
37+
},
38+
}
39+
`);
40+
41+
expect(cjsResult).toMatchInlineSnapshot(`
42+
{
43+
"output": {
44+
"externals": [
45+
/\\^foo\\(\\$\\|\\\\/\\|\\\\\\\\\\)/,
46+
"foo",
47+
],
48+
},
49+
}
50+
`);
51+
});
52+
53+
it('autoExternal should be disabled when format is umd or mf', () => {
54+
const umdResult = composeAutoExternalConfig({
55+
format: 'umd',
56+
autoExternal: undefined,
57+
pkgJson: {
58+
name: 'umd',
59+
dependencies: {
60+
foo: '1.0.0',
61+
},
62+
},
63+
});
64+
65+
expect(umdResult).toMatchInlineSnapshot('{}');
66+
67+
const mfResult = composeAutoExternalConfig({
68+
format: 'mf',
69+
autoExternal: undefined,
70+
pkgJson: {
71+
name: 'mf',
72+
dependencies: {
73+
foo: '1.0.0',
74+
},
75+
},
76+
});
77+
78+
expect(mfResult).toMatchInlineSnapshot('{}');
79+
});
80+
781
it('autoExternal is true', () => {
882
const result = composeAutoExternalConfig({
83+
format: 'esm',
984
autoExternal: true,
1085
pkgJson: {
86+
name: 'esm',
1187
dependencies: {
1288
foo: '1.0.0',
1389
foo1: '1.0.0',
@@ -37,8 +113,10 @@ describe('should composeAutoExternalConfig correctly', () => {
37113

38114
it('autoExternal will deduplication ', () => {
39115
const result = composeAutoExternalConfig({
116+
format: 'esm',
40117
autoExternal: true,
41118
pkgJson: {
119+
name: 'esm',
42120
dependencies: {
43121
foo: '1.0.0',
44122
foo1: '1.0.0',
@@ -70,11 +148,13 @@ describe('should composeAutoExternalConfig correctly', () => {
70148

71149
it('autoExternal is object', () => {
72150
const result = composeAutoExternalConfig({
151+
format: 'esm',
73152
autoExternal: {
74153
peerDependencies: false,
75154
devDependencies: true,
76155
},
77156
pkgJson: {
157+
name: 'esm',
78158
dependencies: {
79159
foo: '1.0.0',
80160
},
@@ -96,8 +176,10 @@ describe('should composeAutoExternalConfig correctly', () => {
96176

97177
it('autoExternal is false', () => {
98178
const result = composeAutoExternalConfig({
179+
format: 'esm',
99180
autoExternal: false,
100181
pkgJson: {
182+
name: 'esm',
101183
dependencies: {
102184
foo: '1.0.0',
103185
},
@@ -109,8 +191,10 @@ describe('should composeAutoExternalConfig correctly', () => {
109191

110192
it('autoExternal with user externals object', () => {
111193
const result = composeAutoExternalConfig({
194+
format: 'esm',
112195
autoExternal: true,
113196
pkgJson: {
197+
name: 'esm',
114198
dependencies: {
115199
foo: '1.0.0',
116200
bar: '1.0.0',
@@ -130,6 +214,7 @@ describe('should composeAutoExternalConfig correctly', () => {
130214

131215
it('read package.json failed', () => {
132216
const result = composeAutoExternalConfig({
217+
format: 'esm',
133218
autoExternal: true,
134219
});
135220

tests/integration/umd-library-name/rslib.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ export default defineConfig({
1414
},
1515
output: {
1616
target: 'web',
17+
externals: {
18+
react: 'react',
19+
},
1720
},
1821
});

website/docs/en/config/lib/auto-external.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type AutoExternal =
2121

2222
Whether to automatically externalize dependencies of different dependency types and do not bundle them.
2323

24+
This option only takes effect when [format](/config/lib/format) is `cjs` or `esm`.
25+
2426
## Object Type
2527

2628
### autoExternal.dependencies

website/docs/en/guide/advanced/third-party-deps.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ In addition to `"dependencies"`, `"peerDependencies"`can also declare dependenci
1515

1616
## Default handling of third-party dependencies
1717

18-
By default, third-party dependencies under `"dependencies"`, `"optionalDependencies"` and `"peerDependencies"` are not bundled by Rslib.
18+
By default, when generating CJS or ESM outputs, third-party dependencies under `"dependencies"`, `"optionalDependencies"` and `"peerDependencies"` are not bundled by Rslib.
1919

2020
This is because when the npm package is installed, its `"dependencies"` will also be installed. By not packaging `"dependencies"`, you can reduce the size of the package product.
2121

website/docs/zh/config/lib/auto-external.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type AutoExternal =
2121

2222
是否自动对不同依赖类型的依赖进行外部化处理,不将其打包。
2323

24+
该选项仅当 [format](/config/lib/format)`cjs``esm` 时生效。
25+
2426
## 对象类型
2527

2628
### autoExternal.dependencies

website/docs/zh/guide/advanced/third-party-deps.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
## 三方依赖的默认处理
1717

18-
默认情况下,`dependencies``optionalDependencies``peerDependencies` 字段下的三方依赖不会被 Rslib 打包。
18+
默认情况下,当生成 CJS 或 ESM 产物时,`dependencies``optionalDependencies``peerDependencies` 字段下的三方依赖不会被 Rslib 打包。
1919

2020
这是因为在 npm 包安装时,其 `dependencies` 也会被安装。通过不打包 `dependencies`,可以减少包的体积。
2121

0 commit comments

Comments
 (0)