Skip to content

Commit 399c083

Browse files
feat: autoExternal default to false when format is umd or mf (#531)
Co-authored-by: Wei <[email protected]>
1 parent 2a74a2f commit 399c083

File tree

9 files changed

+166
-12
lines changed

9 files changed

+166
-12
lines changed

packages/core/src/config.ts

Lines changed: 21 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,
@@ -234,14 +235,27 @@ const composeExternalsWarnConfig = (
234235
};
235236
};
236237

238+
const getAutoExternalDefaultValue = (
239+
format: Format,
240+
autoExternal?: AutoExternal,
241+
): AutoExternal => {
242+
return autoExternal ?? isIntermediateOutputFormat(format);
243+
};
244+
237245
export const composeAutoExternalConfig = (options: {
238-
autoExternal: AutoExternal;
246+
format: Format;
247+
autoExternal?: AutoExternal;
239248
pkgJson?: PkgJson;
240249
userExternals?: NonNullable<RsbuildConfig['output']>['externals'];
241250
}): RsbuildConfig => {
242-
const { autoExternal, pkgJson, userExternals } = options;
251+
const { format, pkgJson, userExternals } = options;
243252

244-
if (!autoExternal) {
253+
const autoExternal = getAutoExternalDefaultValue(
254+
format,
255+
options.autoExternal,
256+
);
257+
258+
if (autoExternal === false) {
245259
return {};
246260
}
247261

@@ -1005,7 +1019,7 @@ const composeDtsConfig = async (
10051019
libConfig: LibConfig,
10061020
dtsExtension: string,
10071021
): Promise<RsbuildConfig> => {
1008-
const { autoExternal, banner, footer } = libConfig;
1022+
const { format, autoExternal, banner, footer } = libConfig;
10091023

10101024
let { dts } = libConfig;
10111025

@@ -1028,7 +1042,7 @@ const composeDtsConfig = async (
10281042
build: dts?.build,
10291043
abortOnError: dts?.abortOnError,
10301044
dtsExtension: dts?.autoExtension ? dtsExtension : '.d.ts',
1031-
autoExternal,
1045+
autoExternal: getAutoExternalDefaultValue(format!, autoExternal),
10321046
banner: banner?.dts,
10331047
footer: footer?.dts,
10341048
}),
@@ -1150,7 +1164,7 @@ async function composeLibRsbuildConfig(config: LibConfig) {
11501164
banner = {},
11511165
footer = {},
11521166
autoExtension = true,
1153-
autoExternal = true,
1167+
autoExternal,
11541168
externalHelpers = false,
11551169
redirect = {},
11561170
umdName,
@@ -1190,6 +1204,7 @@ async function composeLibRsbuildConfig(config: LibConfig) {
11901204
);
11911205
const syntaxConfig = composeSyntaxConfig(target, config?.syntax);
11921206
const autoExternalConfig = composeAutoExternalConfig({
1207+
format: format!,
11931208
autoExternal,
11941209
pkgJson,
11951210
userExternals: config.output?.externals,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +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-
* @defaultValue `true`
112+
* @defaultValue `true` when {@link format} is `cjs` or `esm`, `false` when {@link format} is `umd` or `mf`.
113113
* @see {@link https://lib.rsbuild.dev/config/lib/auto-external}
114114
*/
115115
autoExternal?: AutoExternal;

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: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,83 @@ import { composeAutoExternalConfig } from '../src/config';
44
vi.mock('rslog');
55

66
describe('should composeAutoExternalConfig correctly', () => {
7+
it('autoExternal default value', () => {
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+
const umdResult = composeAutoExternalConfig({
31+
format: 'umd',
32+
autoExternal: undefined,
33+
pkgJson: {
34+
name: 'umd',
35+
dependencies: {
36+
foo: '1.0.0',
37+
},
38+
},
39+
});
40+
41+
const mfResult = composeAutoExternalConfig({
42+
format: 'mf',
43+
autoExternal: undefined,
44+
pkgJson: {
45+
name: 'mf',
46+
dependencies: {
47+
foo: '1.0.0',
48+
},
49+
},
50+
});
51+
52+
expect(esmResult).toMatchInlineSnapshot(`
53+
{
54+
"output": {
55+
"externals": [
56+
/\\^foo\\(\\$\\|\\\\/\\|\\\\\\\\\\)/,
57+
"foo",
58+
],
59+
},
60+
}
61+
`);
62+
63+
expect(cjsResult).toMatchInlineSnapshot(`
64+
{
65+
"output": {
66+
"externals": [
67+
/\\^foo\\(\\$\\|\\\\/\\|\\\\\\\\\\)/,
68+
"foo",
69+
],
70+
},
71+
}
72+
`);
73+
74+
expect(umdResult).toMatchInlineSnapshot('{}');
75+
expect(mfResult).toMatchInlineSnapshot('{}');
76+
});
77+
778
it('autoExternal is true', () => {
879
const result = composeAutoExternalConfig({
80+
format: 'esm',
981
autoExternal: true,
1082
pkgJson: {
83+
name: 'esm',
1184
dependencies: {
1285
foo: '1.0.0',
1386
foo1: '1.0.0',
@@ -35,10 +108,58 @@ describe('should composeAutoExternalConfig correctly', () => {
35108
});
36109
});
37110

111+
it('autoExternal is true when format is umd or mf', () => {
112+
const umdResult = composeAutoExternalConfig({
113+
format: 'umd',
114+
autoExternal: true,
115+
pkgJson: {
116+
name: 'umd',
117+
dependencies: {
118+
foo: '1.0.0',
119+
},
120+
},
121+
});
122+
123+
expect(umdResult).toMatchInlineSnapshot(`
124+
{
125+
"output": {
126+
"externals": [
127+
/\\^foo\\(\\$\\|\\\\/\\|\\\\\\\\\\)/,
128+
"foo",
129+
],
130+
},
131+
}
132+
`);
133+
134+
const mfResult = composeAutoExternalConfig({
135+
format: 'mf',
136+
autoExternal: true,
137+
pkgJson: {
138+
name: 'mf',
139+
dependencies: {
140+
foo: '1.0.0',
141+
},
142+
},
143+
});
144+
145+
expect(mfResult).toMatchInlineSnapshot(`
146+
{
147+
"output": {
148+
"externals": [
149+
/\\^foo\\(\\$\\|\\\\/\\|\\\\\\\\\\)/,
150+
"foo",
151+
],
152+
},
153+
}
154+
`);
155+
});
156+
38157
it('autoExternal will deduplication ', () => {
39158
const result = composeAutoExternalConfig({
159+
format: 'esm',
40160
autoExternal: true,
41161
pkgJson: {
162+
name: 'esm',
42163
dependencies: {
43164
foo: '1.0.0',
44165
foo1: '1.0.0',
@@ -70,11 +191,13 @@ describe('should composeAutoExternalConfig correctly', () => {
70191

71192
it('autoExternal is object', () => {
72193
const result = composeAutoExternalConfig({
194+
format: 'esm',
73195
autoExternal: {
74196
peerDependencies: false,
75197
devDependencies: true,
76198
},
77199
pkgJson: {
200+
name: 'esm',
78201
dependencies: {
79202
foo: '1.0.0',
80203
},
@@ -96,8 +219,10 @@ describe('should composeAutoExternalConfig correctly', () => {
96219

97220
it('autoExternal is false', () => {
98221
const result = composeAutoExternalConfig({
222+
format: 'esm',
99223
autoExternal: false,
100224
pkgJson: {
225+
name: 'esm',
101226
dependencies: {
102227
foo: '1.0.0',
103228
},
@@ -109,8 +234,10 @@ describe('should composeAutoExternalConfig correctly', () => {
109234

110235
it('autoExternal with user externals object', () => {
111236
const result = composeAutoExternalConfig({
237+
format: 'esm',
112238
autoExternal: true,
113239
pkgJson: {
240+
name: 'esm',
114241
dependencies: {
115242
foo: '1.0.0',
116243
bar: '1.0.0',
@@ -130,6 +257,7 @@ describe('should composeAutoExternalConfig correctly', () => {
130257

131258
it('read package.json failed', () => {
132259
const result = composeAutoExternalConfig({
260+
format: 'esm',
133261
autoExternal: true,
134262
});
135263

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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ type AutoExternal =
1717
};
1818
```
1919

20-
- **Default:** `true`
20+
- **Default:**
21+
- `true` when [format](/config/lib/format) is `cjs` or `esm`
22+
- `false` when [format](/config/lib/format) is `umd` or `mf`
2123

2224
Whether to automatically externalize dependencies of different dependency types and do not bundle them.
2325

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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ type AutoExternal =
1717
};
1818
```
1919

20-
- **默认值:** `true`
20+
- **默认值:**
21+
-[format](/config/lib/format)`cjs``esm` 时为 `true`
22+
-[format](/config/lib/format)`umd``mf` 时为 `false`
2123

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

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)