Skip to content

Commit b6b21b3

Browse files
authored
feat!: disable autoExternal in bundleless mode and only redirect request not in node_modules (#624)
1 parent b1cffee commit b6b21b3

File tree

17 files changed

+138
-57
lines changed

17 files changed

+138
-57
lines changed

packages/core/src/config.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,18 @@ const getAutoExternalDefaultValue = (
250250
};
251251

252252
export const composeAutoExternalConfig = (options: {
253+
bundle: boolean;
253254
format: Format;
254255
autoExternal?: AutoExternal;
255256
pkgJson?: PkgJson;
256257
userExternals?: NonNullable<EnvironmentConfig['output']>['externals'];
257258
}): EnvironmentConfig => {
258-
const { format, pkgJson, userExternals } = options;
259+
const { bundle, format, pkgJson, userExternals } = options;
260+
261+
// If bundle is false, autoExternal will be disabled
262+
if (bundle === false) {
263+
return {};
264+
}
259265

260266
const autoExternal = getAutoExternalDefaultValue(
261267
format,
@@ -1020,23 +1026,33 @@ const composeBundlelessExternalConfig = (
10201026

10211027
if (jsRedirectPath) {
10221028
try {
1029+
// use resolver to resolve the request
10231030
resolvedRequest = await resolver(context, resolvedRequest);
1024-
resolvedRequest = normalizeSlash(
1025-
path.relative(
1026-
path.dirname(contextInfo.issuer),
1027-
resolvedRequest,
1028-
),
1029-
);
1030-
// Requests that fall through here cannot be matched by any other externals config ahead.
1031-
// Treat all these requests as relative import of source code. Node.js won't add the
1032-
// leading './' to the relative path resolved by `path.relative`. So add manually it here.
1033-
if (resolvedRequest[0] !== '.') {
1034-
resolvedRequest = `./${resolvedRequest}`;
1031+
1032+
// only handle the request that is not in node_modules
1033+
if (!resolvedRequest.includes('node_modules')) {
1034+
resolvedRequest = normalizeSlash(
1035+
path.relative(
1036+
path.dirname(contextInfo.issuer),
1037+
resolvedRequest,
1038+
),
1039+
);
1040+
// Requests that fall through here cannot be matched by any other externals config ahead.
1041+
// Treat all these requests as relative import of source code. Node.js won't add the
1042+
// leading './' to the relative path resolved by `path.relative`. So add manually it here.
1043+
if (resolvedRequest[0] !== '.') {
1044+
resolvedRequest = `./${resolvedRequest}`;
1045+
}
1046+
} else {
1047+
// NOTE: If request is a phantom dependency, which means it can be resolved but not specified in dependencies or peerDependencies in package.json, the output will be incorrect to use when the package is published
1048+
// return the original request instead of the resolved request
1049+
return callback(undefined, request);
10351050
}
10361051
} catch (e) {
1052+
// catch error when request can not be resolved by resolver
10371053
// e.g. A react component library importing and using 'react' but while not defining
10381054
// it in devDependencies and peerDependencies. Preserve 'react' as-is if so.
1039-
logger.warn(
1055+
logger.debug(
10401056
`Failed to resolve module ${color.green(`"${resolvedRequest}"`)} from ${color.green(contextInfo.issuer)}. If it's an npm package, consider adding it to dependencies or peerDependencies in package.json to make it externalized.`,
10411057
);
10421058
}
@@ -1271,6 +1287,7 @@ async function composeLibRsbuildConfig(
12711287
} = composeTargetConfig(config.output?.target, format!);
12721288
const syntaxConfig = composeSyntaxConfig(target, config?.syntax);
12731289
const autoExternalConfig = composeAutoExternalConfig({
1290+
bundle,
12741291
format: format!,
12751292
autoExternal,
12761293
pkgJson,

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "auto-external-bundle-false-test",
3+
"private": true,
4+
"devDependencies": {
5+
"ora": "8.1.1",
6+
"react": "^19.0.0"
7+
}
8+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig({
7+
bundle: false,
8+
}),
9+
generateBundleCjsConfig({
10+
bundle: false,
11+
}),
12+
],
13+
source: {
14+
entry: {
15+
index: ['./src/**'],
16+
},
17+
},
18+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { oraPromise } from 'ora';
2+
import React from 'react';
3+
4+
export type { oraPromise };
5+
export const foo = () => {
6+
return React.version;
7+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "@rslib/tsconfig/base",
3+
"compilerOptions": {
4+
"baseUrl": "./"
5+
},
6+
"include": ["src"]
7+
}

tests/integration/auto-external/index.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ test('auto external sub path should works', async () => {
4040
);
4141
});
4242

43+
test('auto external should be disabled when bundle is false', async () => {
44+
const fixturePath = join(__dirname, 'bundle-false');
45+
const { js } = await buildAndGetResults({ fixturePath, type: 'all' });
46+
47+
expect(Object.values(js.contents.esm)[0]).toContain(
48+
'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"',
49+
);
50+
51+
expect(Object.values(js.contents.cjs)[0]).toContain(
52+
'const external_react_namespaceObject = require("react");',
53+
);
54+
});
55+
4356
test('auto external false should works', async () => {
4457
const fixturePath = join(__dirname, 'false');
4558
const { js, dts } = await buildAndGetResults({ fixturePath, type: 'all' });
@@ -49,7 +62,7 @@ test('auto external false should works', async () => {
4962
);
5063

5164
expect(js.entries.cjs).not.toContain(
52-
'var external_react_namespaceObject = require("react");',
65+
'const external_react_namespaceObject = require("react");',
5366
);
5467

5568
// dts should bundled
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
// can not be resolved
12
import lodash from 'lodash';
3+
// can be resolved but not specified -- phantom dependency
4+
import prettier from 'prettier';
25
import bar from './bar.js';
36
import foo from './foo';
47

8+
console.log('prettier: ', prettier);
9+
510
export default lodash.toUpper(foo + bar);

tests/integration/redirect/js.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ test('redirect.js default', async () => {
2121

2222
expect(indexContent).toMatchInlineSnapshot(`
2323
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
24+
import * as __WEBPACK_EXTERNAL_MODULE_prettier__ from "prettier";
2425
import * as __WEBPACK_EXTERNAL_MODULE__bar_index_js__ from "./bar/index.js";
2526
import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";
2627
import * as __WEBPACK_EXTERNAL_MODULE__baz_js__ from "./baz.js";
28+
console.log('prettier: ', __WEBPACK_EXTERNAL_MODULE_prettier__["default"]);
2729
const src_rslib_entry_ = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].toUpper(__WEBPACK_EXTERNAL_MODULE__foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__bar_index_js__.bar + __WEBPACK_EXTERNAL_MODULE__foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__bar_index_js__.bar + __WEBPACK_EXTERNAL_MODULE__baz_js__.baz);
2830
export { src_rslib_entry_ as default };
2931
"
@@ -44,11 +46,13 @@ test('redirect.js.path false', async () => {
4446

4547
expect(indexContent).toMatchInlineSnapshot(`
4648
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
49+
import * as __WEBPACK_EXTERNAL_MODULE_prettier__ from "prettier";
4750
import * as __WEBPACK_EXTERNAL_MODULE__bar__ from "@/bar";
4851
import * as __WEBPACK_EXTERNAL_MODULE__foo__ from "@/foo";
4952
import * as __WEBPACK_EXTERNAL_MODULE__baz__ from "~/baz";
5053
import * as __WEBPACK_EXTERNAL_MODULE__bar_js__ from "./bar.js";
5154
import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";
55+
console.log('prettier: ', __WEBPACK_EXTERNAL_MODULE_prettier__["default"]);
5256
const src_rslib_entry_ = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].toUpper(__WEBPACK_EXTERNAL_MODULE__foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__bar_js__.bar + __WEBPACK_EXTERNAL_MODULE__foo__.foo + __WEBPACK_EXTERNAL_MODULE__bar__.bar + __WEBPACK_EXTERNAL_MODULE__baz__.baz);
5357
export { src_rslib_entry_ as default };
5458
"
@@ -67,11 +71,13 @@ test('redirect.js.path with user override externals', async () => {
6771

6872
expect(indexContent).toMatchInlineSnapshot(`
6973
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
74+
import * as __WEBPACK_EXTERNAL_MODULE_prettier__ from "prettier";
7075
import * as __WEBPACK_EXTERNAL_MODULE__others_bar_index_js__ from "./others/bar/index.js";
7176
import * as __WEBPACK_EXTERNAL_MODULE__others_foo_js__ from "./others/foo.js";
7277
import * as __WEBPACK_EXTERNAL_MODULE__baz_js__ from "./baz.js";
7378
import * as __WEBPACK_EXTERNAL_MODULE__bar_index_js__ from "./bar/index.js";
7479
import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";
80+
console.log('prettier: ', __WEBPACK_EXTERNAL_MODULE_prettier__["default"]);
7581
const src_rslib_entry_ = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].toUpper(__WEBPACK_EXTERNAL_MODULE__foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__bar_index_js__.bar + __WEBPACK_EXTERNAL_MODULE__others_foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__others_bar_index_js__.bar + __WEBPACK_EXTERNAL_MODULE__baz_js__.baz);
7682
export { src_rslib_entry_ as default };
7783
"
@@ -98,11 +104,13 @@ test('redirect.js.path with user override alias', async () => {
98104

99105
expect(indexContent).toMatchInlineSnapshot(`
100106
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
107+
import * as __WEBPACK_EXTERNAL_MODULE_prettier__ from "prettier";
101108
import * as __WEBPACK_EXTERNAL_MODULE__others_bar_index_js__ from "./others/bar/index.js";
102109
import * as __WEBPACK_EXTERNAL_MODULE__others_foo_js__ from "./others/foo.js";
103110
import * as __WEBPACK_EXTERNAL_MODULE__baz_js__ from "./baz.js";
104111
import * as __WEBPACK_EXTERNAL_MODULE__bar_index_js__ from "./bar/index.js";
105112
import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";
113+
console.log('prettier: ', __WEBPACK_EXTERNAL_MODULE_prettier__["default"]);
106114
const src_rslib_entry_ = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].toUpper(__WEBPACK_EXTERNAL_MODULE__foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__bar_index_js__.bar + __WEBPACK_EXTERNAL_MODULE__others_foo_js__.foo + __WEBPACK_EXTERNAL_MODULE__others_bar_index_js__.bar + __WEBPACK_EXTERNAL_MODULE__baz_js__.baz);
107115
export { src_rslib_entry_ as default };
108116
"
@@ -124,9 +132,11 @@ test('redirect.js.extension: false', async () => {
124132
);
125133
expect(indexContent).toMatchInlineSnapshot(`
126134
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
135+
import * as __WEBPACK_EXTERNAL_MODULE_prettier__ from "prettier";
127136
import * as __WEBPACK_EXTERNAL_MODULE__bar_index_ts__ from "./bar/index.ts";
128137
import * as __WEBPACK_EXTERNAL_MODULE__foo_ts__ from "./foo.ts";
129138
import * as __WEBPACK_EXTERNAL_MODULE__baz_ts__ from "./baz.ts";
139+
console.log('prettier: ', __WEBPACK_EXTERNAL_MODULE_prettier__["default"]);
130140
const src_rslib_entry_ = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].toUpper(__WEBPACK_EXTERNAL_MODULE__foo_ts__.foo + __WEBPACK_EXTERNAL_MODULE__bar_index_ts__.bar + __WEBPACK_EXTERNAL_MODULE__foo_ts__.foo + __WEBPACK_EXTERNAL_MODULE__bar_index_ts__.bar + __WEBPACK_EXTERNAL_MODULE__baz_ts__.baz);
131141
export { src_rslib_entry_ as default };
132142
"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
// can not be resolved
12
import lodash from 'lodash';
3+
// can be resolved but not specified -- phantom dependency
4+
import prettier from 'prettier';
25

36
import { bar as bar2 } from '@/bar';
47
import { foo as foo2 } from '@/foo';
58
import { baz } from '~/baz';
69
import { bar } from './bar';
710
import { foo } from './foo';
811

12+
console.log('prettier: ', prettier);
13+
914
export default lodash.toUpper(foo + bar + foo2 + bar2 + baz);

0 commit comments

Comments
 (0)