Skip to content

Commit

Permalink
test: add alias replace externals tests in bundleless mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Timeless0911 committed Dec 19, 2024
1 parent 8a9f9e3 commit 3b63510
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 26 deletions.
19 changes: 19 additions & 0 deletions tests/integration/alias/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,22 @@ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_targe
});
"
`;

exports[`source.alias 3`] = `
"import * as __WEBPACK_EXTERNAL_MODULE__a_js__ from "./a.js";
console.info(__WEBPACK_EXTERNAL_MODULE__a_js__.a);
"
`;

exports[`source.alias 4`] = `
""use strict";
var __webpack_exports__ = {};
const external_a_cjs_namespaceObject = require("./a.cjs");
console.info(external_a_cjs_namespaceObject.a);
var __webpack_export_target__ = exports;
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
value: true
});
"
`;
41 changes: 34 additions & 7 deletions tests/integration/alias/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
import { buildAndGetResults } from 'test-helper';
import { buildAndGetResults, queryContent } from 'test-helper';
import { expect, test } from 'vitest';

test('source.alias', async () => {
const fixturePath = __dirname;
const { entries } = await buildAndGetResults({ fixturePath });
const { contents } = await buildAndGetResults({ fixturePath });

expect(entries.esm).toContain('hello world');
expect(entries.cjs).toContain('hello world');
const { content: indexBundleEsmContent } = queryContent(
contents.esm0!,
/esm\/index\.js/,
);
const { content: indexBundleCjsContent } = queryContent(
contents.cjs0!,
/cjs\/index\.cjs/,
);
const { content: indexBundlelessEsmContent } = queryContent(
contents.esm1!,
/esm\/index\.js/,
);
const { content: indexBundlelessCjsContent } = queryContent(
contents.cjs1!,
/cjs\/index\.cjs/,
);

// simple artifacts check
expect(entries.esm).toMatchSnapshot();
expect(entries.cjs).toMatchSnapshot();
// bundle mode
expect(indexBundleEsmContent).toContain('hello world');
expect(indexBundleCjsContent).toContain('hello world');

// bundleless mode
expect(indexBundlelessEsmContent).toContain(
'import * as __WEBPACK_EXTERNAL_MODULE__a_js__ from "./a.js";',
);
expect(indexBundlelessCjsContent).toContain(
'const external_a_cjs_namespaceObject = require("./a.cjs");',
);

expect(indexBundleEsmContent).toMatchSnapshot();
expect(indexBundleCjsContent).toMatchSnapshot();
expect(indexBundlelessEsmContent).toMatchSnapshot();
expect(indexBundlelessCjsContent).toMatchSnapshot();
});
58 changes: 52 additions & 6 deletions tests/integration/alias/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,58 @@ import { defineConfig } from '@rslib/core';
import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper';

export default defineConfig({
lib: [generateBundleEsmConfig(), generateBundleCjsConfig()],
source: {
entry: {
index: './src/index.ts',
},
},
lib: [
generateBundleEsmConfig({
source: {
entry: {
index: './src/index.ts',
},
},
output: {
distPath: {
root: 'dist/bundle/esm',
},
},
}),
generateBundleCjsConfig({
source: {
entry: {
index: './src/index.ts',
},
},
output: {
distPath: {
root: 'dist/bundle/cjs',
},
},
}),
generateBundleEsmConfig({
bundle: false,
source: {
entry: {
index: './src/**',
},
},
output: {
distPath: {
root: 'dist/bundleless/esm',
},
},
}),
generateBundleCjsConfig({
bundle: false,
source: {
entry: {
index: './src/**',
},
},
output: {
distPath: {
root: 'dist/bundleless/cjs',
},
},
}),
],
resolve: {
alias: {
'@src': 'src',
Expand Down
33 changes: 32 additions & 1 deletion tests/integration/redirect/js.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,40 @@ test('redirect.js.path with user override externals', async () => {
);
});

test('redirect.js.path with user override alias', async () => {
const { content: indexContent, path: indexEsmPath } = queryContent(
contents.esm3!,
/esm\/index\.js/,
);
const { path: indexCjsPath } = await queryContent(
contents.cjs3!,
/cjs\/index\.cjs/,
);

expect(indexContent).toMatchInlineSnapshot(`
"import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
import * as __WEBPACK_EXTERNAL_MODULE__others_bar_index_js__ from "./others/bar/index.js";
import * as __WEBPACK_EXTERNAL_MODULE__others_foo_js__ from "./others/foo.js";
import * as __WEBPACK_EXTERNAL_MODULE__baz_js__ from "./baz.js";
import * as __WEBPACK_EXTERNAL_MODULE__bar_index_js__ from "./bar/index.js";
import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";
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);
export { src_rslib_entry_ as default };
"
`);

const esmResult = await import(indexEsmPath);
const cjsResult = await import(indexCjsPath);

expect(esmResult.default).toEqual(cjsResult.default);
expect(esmResult.default).toMatchInlineSnapshot(
`"FOOBAR1OTHERFOOOTHERBAR2BAZ"`, // cspell:disable-line
);
});

test('redirect.js.extension: false', async () => {
const { content: indexContent } = queryContent(
contents.esm3!,
contents.esm4!,
/esm\/index\.js/,
);
expect(indexContent).toMatchInlineSnapshot(`
Expand Down
39 changes: 35 additions & 4 deletions tests/integration/redirect/js/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ export default defineConfig({
generateBundleEsmConfig({
bundle: false,
output: {
distPath: {
root: 'dist/js-path-externals-override/esm',
},
externals: {
'@/foo': './others/foo.js',
'@/bar': './others/bar/index.js',
},
distPath: {
root: 'dist/js-path-externals-override/esm',
},
},
}),
generateBundleCjsConfig({
Expand All @@ -72,7 +72,38 @@ export default defineConfig({
},
},
}),
// 3 js.extension: false
// 3 js.path with user override alias
generateBundleEsmConfig({
bundle: false,
resolve: {
alias: {
'@/foo': './src/others/foo',
'@/bar': './src/others/bar',
},
aliasStrategy: 'prefer-alias',
},
output: {
distPath: {
root: 'dist/js-path-alias-override/esm',
},
},
}),
generateBundleCjsConfig({
bundle: false,
resolve: {
alias: {
'@/foo': './src/others/foo',
'@/bar': './src/others/bar',
},
aliasStrategy: 'prefer-alias',
},
output: {
distPath: {
root: 'dist/js-path-alias-override/cjs',
},
},
}),
// 4 js.extension: false
generateBundleEsmConfig({
bundle: false,
output: {
Expand Down
4 changes: 4 additions & 0 deletions website/docs/en/config/lib/redirect.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
overviewHeaders: [2, 3]
---

# lib.redirect

:::info
Expand Down
12 changes: 8 additions & 4 deletions website/docs/en/config/rsbuild/resolve.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Control the priority between the `paths` option in `tsconfig.json` and the `reso

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

It is important to note that `resolve.alias` differs from [output.externals](/config/rsbuild/output#outputexternals) in the following ways:
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:

- `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`.
- `resolve.alias` is used to replace the target module with another module, which will be bundled into the output.

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

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

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

- `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.

For example, if you want to replace `react` and `react-dom` with `preact/compat` in the bundle, you can configure it as follows:
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:

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

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

::: note
In bundleless mode, since there is no bundling concept, all modules will be externalized, so we will automatically replace the aliases in `resolve.alias` with `output.externals` to ensure the final output is generated correctly.
:::

## resolve.dedupe <RsbuildDocBadge path="/config/resolve/dedupe" text="resolve.dedupe" />

Force Rsbuild to resolve the specified packages from project root, which is useful for deduplicating packages and reducing the bundle size.
Expand Down
4 changes: 4 additions & 0 deletions website/docs/zh/config/lib/redirect.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
overviewHeaders: [2, 3]
---

# lib.redirect

:::info
Expand Down
12 changes: 8 additions & 4 deletions website/docs/zh/config/rsbuild/resolve.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge';

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

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

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

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

Expand All @@ -29,11 +29,11 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge';
};
```

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

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

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

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

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

::: note
在 bundleless 模式下,由于并没有打包这个概念,所有模块都会被外部化,因此我们会自动将 `resolve.alias` 中的别名替换为 `output.externals` 以确保最终生成正确的产物。
:::

## resolve.dedupe <RsbuildDocBadge path="/config/resolve/dedupe" text="resolve.dedupe" />

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

0 comments on commit 3b63510

Please sign in to comment.