Skip to content

Commit 4416f02

Browse files
authored
test: add alias replace externals tests in bundleless mode (#581)
1 parent 096b7a4 commit 4416f02

File tree

10 files changed

+198
-27
lines changed

10 files changed

+198
-27
lines changed

tests/integration/alias/__snapshots__/index.test.ts.snap

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,22 @@ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_targe
1818
});
1919
"
2020
`;
21+
22+
exports[`source.alias 3`] = `
23+
"import * as __WEBPACK_EXTERNAL_MODULE__a_js__ from "./a.js";
24+
console.info(__WEBPACK_EXTERNAL_MODULE__a_js__.a);
25+
"
26+
`;
27+
28+
exports[`source.alias 4`] = `
29+
""use strict";
30+
var __webpack_exports__ = {};
31+
const external_a_cjs_namespaceObject = require("./a.cjs");
32+
console.info(external_a_cjs_namespaceObject.a);
33+
var __webpack_export_target__ = exports;
34+
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
35+
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
36+
value: true
37+
});
38+
"
39+
`;

tests/integration/alias/index.test.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,41 @@
1-
import { buildAndGetResults } from 'test-helper';
1+
import { buildAndGetResults, queryContent } from 'test-helper';
22
import { expect, test } from 'vitest';
33

44
test('source.alias', async () => {
55
const fixturePath = __dirname;
6-
const { entries } = await buildAndGetResults({ fixturePath });
6+
const { contents } = await buildAndGetResults({ fixturePath });
77

8-
expect(entries.esm).toContain('hello world');
9-
expect(entries.cjs).toContain('hello world');
8+
const { content: indexBundleEsmContent } = queryContent(
9+
contents.esm0!,
10+
/esm\/index\.js/,
11+
);
12+
const { content: indexBundleCjsContent } = queryContent(
13+
contents.cjs0!,
14+
/cjs\/index\.cjs/,
15+
);
16+
const { content: indexBundlelessEsmContent } = queryContent(
17+
contents.esm1!,
18+
/esm\/index\.js/,
19+
);
20+
const { content: indexBundlelessCjsContent } = queryContent(
21+
contents.cjs1!,
22+
/cjs\/index\.cjs/,
23+
);
1024

11-
// simple artifacts check
12-
expect(entries.esm).toMatchSnapshot();
13-
expect(entries.cjs).toMatchSnapshot();
25+
// bundle mode
26+
expect(indexBundleEsmContent).toContain('hello world');
27+
expect(indexBundleCjsContent).toContain('hello world');
28+
29+
// bundleless mode
30+
expect(indexBundlelessEsmContent).toContain(
31+
'import * as __WEBPACK_EXTERNAL_MODULE__a_js__ from "./a.js";',
32+
);
33+
expect(indexBundlelessCjsContent).toContain(
34+
'const external_a_cjs_namespaceObject = require("./a.cjs");',
35+
);
36+
37+
expect(indexBundleEsmContent).toMatchSnapshot();
38+
expect(indexBundleCjsContent).toMatchSnapshot();
39+
expect(indexBundlelessEsmContent).toMatchSnapshot();
40+
expect(indexBundlelessCjsContent).toMatchSnapshot();
1441
});

tests/integration/alias/rslib.config.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,58 @@ import { defineConfig } from '@rslib/core';
22
import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper';
33

44
export default defineConfig({
5-
lib: [generateBundleEsmConfig(), generateBundleCjsConfig()],
6-
source: {
7-
entry: {
8-
index: './src/index.ts',
9-
},
10-
},
5+
lib: [
6+
generateBundleEsmConfig({
7+
source: {
8+
entry: {
9+
index: './src/index.ts',
10+
},
11+
},
12+
output: {
13+
distPath: {
14+
root: 'dist/bundle/esm',
15+
},
16+
},
17+
}),
18+
generateBundleCjsConfig({
19+
source: {
20+
entry: {
21+
index: './src/index.ts',
22+
},
23+
},
24+
output: {
25+
distPath: {
26+
root: 'dist/bundle/cjs',
27+
},
28+
},
29+
}),
30+
generateBundleEsmConfig({
31+
bundle: false,
32+
source: {
33+
entry: {
34+
index: './src/**',
35+
},
36+
},
37+
output: {
38+
distPath: {
39+
root: 'dist/bundleless/esm',
40+
},
41+
},
42+
}),
43+
generateBundleCjsConfig({
44+
bundle: false,
45+
source: {
46+
entry: {
47+
index: './src/**',
48+
},
49+
},
50+
output: {
51+
distPath: {
52+
root: 'dist/bundleless/cjs',
53+
},
54+
},
55+
}),
56+
],
1157
resolve: {
1258
alias: {
1359
'@src': 'src',

tests/integration/redirect/js.test.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,40 @@ test('redirect.js.path with user override externals', async () => {
8686
);
8787
});
8888

89+
test('redirect.js.path with user override alias', async () => {
90+
const { content: indexContent, path: indexEsmPath } = queryContent(
91+
contents.esm3!,
92+
/esm\/index\.js/,
93+
);
94+
const { path: indexCjsPath } = await queryContent(
95+
contents.cjs3!,
96+
/cjs\/index\.cjs/,
97+
);
98+
99+
expect(indexContent).toMatchInlineSnapshot(`
100+
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
101+
import * as __WEBPACK_EXTERNAL_MODULE__others_bar_index_js__ from "./others/bar/index.js";
102+
import * as __WEBPACK_EXTERNAL_MODULE__others_foo_js__ from "./others/foo.js";
103+
import * as __WEBPACK_EXTERNAL_MODULE__baz_js__ from "./baz.js";
104+
import * as __WEBPACK_EXTERNAL_MODULE__bar_index_js__ from "./bar/index.js";
105+
import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";
106+
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);
107+
export { src_rslib_entry_ as default };
108+
"
109+
`);
110+
111+
const esmResult = await import(indexEsmPath);
112+
const cjsResult = await import(indexCjsPath);
113+
114+
expect(esmResult.default).toEqual(cjsResult.default);
115+
expect(esmResult.default).toMatchInlineSnapshot(
116+
`"FOOBAR1OTHERFOOOTHERBAR2BAZ"`, // cspell:disable-line
117+
);
118+
});
119+
89120
test('redirect.js.extension: false', async () => {
90121
const { content: indexContent } = queryContent(
91-
contents.esm3!,
122+
contents.esm4!,
92123
/esm\/index\.js/,
93124
);
94125
expect(indexContent).toMatchInlineSnapshot(`

tests/integration/redirect/js/rslib.config.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ export default defineConfig({
5151
generateBundleEsmConfig({
5252
bundle: false,
5353
output: {
54+
distPath: {
55+
root: 'dist/js-path-externals-override/esm',
56+
},
5457
externals: {
5558
'@/foo': './others/foo.js',
5659
'@/bar': './others/bar/index.js',
5760
},
58-
distPath: {
59-
root: 'dist/js-path-externals-override/esm',
60-
},
6161
},
6262
}),
6363
generateBundleCjsConfig({
@@ -72,7 +72,38 @@ export default defineConfig({
7272
},
7373
},
7474
}),
75-
// 3 js.extension: false
75+
// 3 js.path with user override alias
76+
generateBundleEsmConfig({
77+
bundle: false,
78+
resolve: {
79+
alias: {
80+
'@/foo': './src/others/foo',
81+
'@/bar': './src/others/bar',
82+
},
83+
aliasStrategy: 'prefer-alias',
84+
},
85+
output: {
86+
distPath: {
87+
root: 'dist/js-path-alias-override/esm',
88+
},
89+
},
90+
}),
91+
generateBundleCjsConfig({
92+
bundle: false,
93+
resolve: {
94+
alias: {
95+
'@/foo': './src/others/foo',
96+
'@/bar': './src/others/bar',
97+
},
98+
aliasStrategy: 'prefer-alias',
99+
},
100+
output: {
101+
distPath: {
102+
root: 'dist/js-path-alias-override/cjs',
103+
},
104+
},
105+
}),
106+
// 4 js.extension: false
76107
generateBundleEsmConfig({
77108
bundle: false,
78109
output: {

tests/integration/server/index.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ describe('server config', async () => {
3131
});
3232

3333
await awaitFileExists(rsbuildConfigFile);
34-
childProcess.kill();
3534

3635
// Check if the server config is merged correctly
3736
const rsbuildConfigContent = await fse.readFile(rsbuildConfigFile, 'utf-8');
3837
expect(rsbuildConfigContent).toContain(`base: '/'`);
3938
expect(rsbuildConfigContent).toContain('open: true');
4039
expect(rsbuildConfigContent).toContain('port: 3002');
4140
expect(rsbuildConfigContent).toContain('printUrls: false');
41+
42+
childProcess.kill();
4243
});
4344
});

website/docs/en/config/lib/redirect.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
overviewHeaders: [2, 3]
3+
---
4+
15
# lib.redirect
26

37
:::info

website/docs/en/config/rsbuild/resolve.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Control the priority between the `paths` option in `tsconfig.json` and the `reso
1212

1313
Create aliases to import or require certain modules, same as the [resolve.alias](https://rspack.dev/config/resolve#resolvealias) config of Rspack.
1414

15-
It is important to note that `resolve.alias` differs from [output.externals](/config/rsbuild/output#outputexternals) in the following ways:
15+
It is worth noting that in bundle mode, both `resolve.alias` and [output.externals](/config/rsbuild/output#outputexternals) can be used to set aliases, but they differ in the following ways:
1616

17-
- `resolve.alias` allows you to replace the target module you want to include in the output bundles with another module. It only works if [lib.bundle](/config/lib/bundle) is set to `true`.
17+
- `resolve.alias` is used to replace the target module with another module, which will be bundled into the output.
1818

1919
For example, if you want to replace `lodash` with `lodash-es` when bundling a package, you can configure it as follows:
2020

@@ -29,11 +29,11 @@ It is important to note that `resolve.alias` differs from [output.externals](/co
2929
};
3030
```
3131

32-
All `lodash` modules imported in the source code will be mapped to `lodash-es` and be bundled into the output.
32+
Now, all `lodash` imports in the source code will be mapped to `lodash-es` and bundled into the output.
3333

3434
- `output.externals` is used to handle alias mapping for externalized modules. Externalized modules are not included in the bundle; instead, they are imported from external sources at runtime.
3535

36-
For example, if you want to replace `react` and `react-dom` with `preact/compat` in the bundle, you can configure it as follows:
36+
For example, if you want to replace externalized modules `react` and `react-dom` with `preact/compat` in the bundle, you can configure it as follows:
3737

3838
```ts title="rslib.config.ts"
3939
export default {
@@ -49,6 +49,10 @@ It is important to note that `resolve.alias` differs from [output.externals](/co
4949

5050
Now, the code `import { useState } from 'react'` will be replaced with `import { useState } from 'preact/compat'`.
5151

52+
::: note
53+
In bundleless mode, since there is no bundling concept, all modules will be externalized, so Rslib will automatically externalize the aliased module in the final output by using `output.externals`.
54+
:::
55+
5256
## resolve.dedupe <RsbuildDocBadge path="/config/resolve/dedupe" text="resolve.dedupe" />
5357

5458
Force Rsbuild to resolve the specified packages from project root, which is useful for deduplicating packages and reducing the bundle size.

website/docs/zh/config/lib/redirect.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
overviewHeaders: [2, 3]
3+
---
4+
15
# lib.redirect
26

37
:::info

website/docs/zh/config/rsbuild/resolve.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge';
1212

1313
设置文件引用的别名,对应 Rspack 的 [resolve.alias](https://rspack.dev/zh/config/resolve#resolvealias) 配置。
1414

15-
值得注意的是,`resolve.alias`[output.externals](/config/rsbuild/output#outputexternals) 在以下方面有所不同
15+
值得注意的是,在 bundle 模式下,`resolve.alias`[output.externals](/config/rsbuild/output#outputexternals) 都可以用于设置别名,但它们在以下方面有所不同
1616

17-
- `resolve.alias` 允许你将目标模块替换为另一个模块。它仅在 [lib.bundle](/config/lib/bundle) 设置为 `true` 时有效
17+
- `resolve.alias` 用于将目标模块替换为另一个模块,该模块会被打包到产物中
1818

1919
例如,如果你想在打包一个 package 时将 `lodash` 替换为 `lodash-es`,可以这样配置:
2020

@@ -29,11 +29,11 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge';
2929
};
3030
```
3131

32-
所有在源代码中导入的 `lodash` 模块将被映射为 `lodash-es`,并被打包到产物中。
32+
此时,所有在源代码中导入的 `lodash` 模块将被映射为 `lodash-es`,并被打包到产物中。
3333

3434
- `output.externals` 用于处理外部化模块的别名映射。外部化模块不会被打包到产物中,而是在运行时从外部源导入。
3535

36-
例如,如果你想在 bundle 中将 `react``react-dom` 替换为 `preact/compat`,可以这样配置:
36+
例如,如果你想将产物中的外部化模块 `react``react-dom` 替换为 `preact/compat`,可以这样配置:
3737

3838
```ts title="rslib.config.ts"
3939
export default {
@@ -49,6 +49,10 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge';
4949

5050
此时,代码 `import { useState } from 'react'` 将被替换为 `import { useState } from 'preact/compat'`
5151

52+
::: note
53+
在 bundleless 模式下,由于并没有打包这个概念,所有模块都会被外部化,因此 Rslib 会自动将 `resolve.alias` 中解析的模块通过 `output.externals` 外部化。
54+
:::
55+
5256
## resolve.dedupe <RsbuildDocBadge path="/config/resolve/dedupe" text="resolve.dedupe" />
5357

5458
强制 Rsbuild 从项目根目录解析指定的包,这可以用于移除重复包和减少包大小。

0 commit comments

Comments
 (0)