Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add alias replace externals tests in bundleless mode #581

Merged
merged 4 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
3 changes: 2 additions & 1 deletion tests/integration/server/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ describe('server config', async () => {
});

await awaitFileExists(rsbuildConfigFile);
childProcess.kill();

// Check if the server config is merged correctly
const rsbuildConfigContent = await fse.readFile(rsbuildConfigFile, 'utf-8');
expect(rsbuildConfigContent).toContain(`base: '/'`);
expect(rsbuildConfigContent).toContain('open: true');
expect(rsbuildConfigContent).toContain('port: 3002');
expect(rsbuildConfigContent).toContain('printUrls: false');

childProcess.kill();
});
});
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 Rslib will automatically externalize the aliased module in the final output by using `output.externals`.
:::

## 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 模式下,由于并没有打包这个概念,所有模块都会被外部化,因此 Rslib 会自动将 `resolve.alias` 中解析的模块通过 `output.externals` 外部化。
:::

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

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