Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 9 additions & 0 deletions packages/core/src/cli/commands.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { RsbuildMode } from '@rsbuild/core';
import cac, { type CAC } from 'cac';
import type { ConfigLoader } from '../config';
import { logger } from '../utils/logger';
import { build } from './build';
import { init } from './init';
Expand All @@ -13,6 +14,7 @@ export type CommonOptions = {
envDir?: string;
envMode?: string;
lib?: string[];
configLoader?: ConfigLoader;
};

export type BuildOptions = CommonOptions & {
Expand All @@ -39,6 +41,13 @@ const applyCommonOptions = (cli: CAC) => {
'--env-mode <mode>',
'specify the env mode to load the `.env.[mode]` file',
)
.option(
'--config-loader <loader>',
'Set the config file loader (jiti | native)',
{
default: 'jiti',
},
)
.option('--env-dir <dir>', 'specify the directory to load `.env` files')
.option(
'--lib <id>',
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/cli/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export async function init(options: CommonOptions): Promise<{
cwd: root,
path: options.config,
envMode: options.envMode,
loader: options.configLoader,
});

config.source ||= {};
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,18 @@ const resolveConfigPath = (root: string, customConfig?: string): string => {
throw new Error(`${DEFAULT_CONFIG_NAME} not found in ${root}`);
};

export type ConfigLoader = 'jiti' | 'native';

export async function loadConfig({
cwd = process.cwd(),
path,
envMode,
loader,
}: {
cwd?: string;
path?: string;
envMode?: string;
loader?: ConfigLoader;
}): Promise<{
content: RslibConfig;
filePath: string;
Expand All @@ -136,6 +140,7 @@ export async function loadConfig({
cwd: dirname(configFilePath),
path: configFilePath,
envMode,
loader,
});

return { content: content as RslibConfig, filePath: configFilePath };
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/cli/build/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@ describe('build command', async () => {
`);
});

test('--config-loader', async () => {
// Skip Node.js <= 22.18
if (!process.features.typescript) {
return;
}

await fse.remove(path.join(__dirname, 'dist'));
runCliSync('build --config-loader native', {
cwd: __dirname,
});

const files = await globContentJSON(path.join(__dirname, 'dist'));
const fileNames = Object.keys(files).sort();
expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/build/dist/cjs/index.cjs",
"<ROOT>/tests/integration/cli/build/dist/esm/index.js",
]
`);
});

test('--root', async () => {
await fse.remove(path.join(__dirname, 'dist'));
runCliSync('build --root custom-root', {
Expand Down
4 changes: 2 additions & 2 deletions tests/scripts/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './helper';
export * from './shared';
export * from './helper.ts';
export * from './shared.ts';
2 changes: 1 addition & 1 deletion tests/scripts/rstest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file can only be imported by @rstest/core test files
import { expect } from '@rstest/core';
import { getFileBySuffix } from './shared';
import { getFileBySuffix } from './shared.ts';

export function expectFileContainContent(
files: Record<string, string>,
Expand Down
2 changes: 1 addition & 1 deletion tests/scripts/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@rsbuild/core';
import type { Format, LibConfig, RslibConfig } from '@rslib/core';
import { build, loadConfig } from '@rslib/core';
import { globContentJSON } from './helper';
import { globContentJSON } from './helper.ts';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Expand Down
10 changes: 10 additions & 0 deletions tests/scripts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext",
"allowImportingTsExtensions": true
},
"include": ["./*.ts"],
"exclude": ["**/node_modules", "**/.*/"]
}
3 changes: 1 addition & 2 deletions tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
"integration/**/rslib.config.ts",
"integration/**/rslib.config.js",
"benchmark/**/*.ts",
"playwright.config.ts",
"scripts"
"playwright.config.ts"
],
"exclude": ["**/node_modules", "**/.*/"],
"references": [
Expand Down
17 changes: 9 additions & 8 deletions website/docs/en/guide/basic/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ Commands:

Rslib CLI provides several common flags that can be used with all commands:

| Flag | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-c, --config <config>` | Specify the configuration file, can be a relative or absolute path, see [Specify config file](/guide/basic/configure-rslib#specify-config-file) |
| `--env-dir <dir>` | Specify the directory to load `.env` files, see [Rsbuild - Env directory](https://rsbuild.rs/guide/advanced/env-vars#env-directory) |
| `--env-mode <mode>` | Specify the env mode to load the `.env.[mode]` file, see [Rsbuild - Env mode](https://rsbuild.rs/guide/advanced/env-vars#env-mode) |
| `-h, --help` | Display help for command |
| `--lib <id>` | Specify the library to run commands (repeatable, e.g. `--lib esm --lib cjs`), see [lib.id](/config/lib/id) to learn how to get or set the ID of the library |
| `-r, --root <root>` | Specify the project root directory, can be an absolute path or a path relative to cwd |
| Flag | Description |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-c, --config <config>` | Specify the configuration file, can be a relative or absolute path, see [Specify config file](/guide/basic/configure-rslib#specify-config-file) |
| `--config-loader <loader>` | Set the config file loader (`jiti` \| `native`), see [Specify config loader](/guide/basic/configure-rslib#specify-config-loader) |
| `--env-dir <dir>` | Specify the directory to load `.env` files, see [Rsbuild - Env directory](https://rsbuild.rs/guide/advanced/env-vars#env-directory) |
| `--env-mode <mode>` | Specify the env mode to load the `.env.[mode]` file, see [Rsbuild - Env mode](https://rsbuild.rs/guide/advanced/env-vars#env-mode) |
| `-h, --help` | Display help for command |
| `--lib <id>` | Specify the library to run commands (repeatable, e.g. `--lib esm --lib cjs`), see [lib.id](/config/lib/id) to learn how to get or set the ID of the library |
| `-r, --root <root>` | Specify the project root directory, can be an absolute path or a path relative to cwd |

## rslib build

Expand Down
20 changes: 20 additions & 0 deletions website/docs/en/guide/basic/configure-rslib.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,26 @@ You can also abbreviate the `--config` option to `-c`:
rslib build -c rslib.prod.config.mjs
```

## Specify config loader

When you use a configuration file with the `.ts`, `.mts`, and `.cts` extensions, Rslib will use [jiti](https://github.com/unjs/jiti) to load configuration files, providing interoperability between ESM and CommonJS. The behavior of module resolution differs slightly from the native behavior of Node.js.

If your JavaScript runtime already natively supports TypeScript, you can use the `--config-loader native` option to use the Node.js native loader to load the configuration file. This can ensure that the module resolution behavior is consistent with the native behavior of Node.js and has better performance.

For example, Node.js v22.6.0+ already natively supports TypeScript, you can use the following command to use the Node.js native loader to load the configuration file:

```bash
# Node.js >= v22.18.0
# No need to set --experimental-strip-types
npx rslib build --config-loader native

# Node.js v22.6.0 - v22.17.0
# Need to set --experimental-strip-types
NODE_OPTIONS="--experimental-strip-types" npx rslib build --config-loader native
```

> See [Node.js - Running TypeScript Natively](https://nodejs.org/en/learn/typescript/run-natively#running-typescript-natively) for more details.

## Using environment variables

In the configuration file, you can use Node.js environment variables such as `process.env.NODE_ENV` to dynamically set different configurations:
Expand Down
17 changes: 9 additions & 8 deletions website/docs/zh/guide/basic/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ Commands:

Rslib CLI 提供了一些公共选项,可以用于所有命令:

| 选项 | 描述 |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `-c, --config <config>` | 指定配置文件路径,可以为相对路径或绝对路径,详见 [指定配置文件](/guide/basic/configure-rslib#指定配置文件) |
| `--env-dir <dir>` | 指定目录来加载 `.env` 文件,详见 [Rsbuild - Env 目录](https://rsbuild.rs/zh/guide/advanced/env-vars#env-目录) |
| `--env-mode <mode>` | 指定 env 模式来加载 `.env.[mode]` 文件,详见 [Rsbuild - Env 模式](https://rsbuild.rs/zh/guide/advanced/env-vars#env-模式) |
| `-h, --help` | 显示命令帮助 |
| `--lib <id>` | 指定运行命令的库(可重复,例如:`--lib esm --lib cjs`),查看 [lib.id](/config/lib/id) 了解如何获取或设置库的 ID |
| `-r, --root <root>` | 指定项目根目录,可以是绝对路径或者相对于 cwd 的路径 |
| 选项 | 描述 |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `-c, --config <config>` | 指定配置文件路径,可以为相对路径或绝对路径,详见 [指定配置文件](/guide/basic/configure-rslib#指定配置文件) |
| `--config-loader <loader>` | 指定配置文件加载方式(`jiti` \| `native`),详见 [指定加载方式](/guide/basic/configure-rslib#指定加载方式) |
| `--env-dir <dir>` | 指定目录来加载 `.env` 文件,详见 [Rsbuild - Env 目录](https://rsbuild.rs/zh/guide/advanced/env-vars#env-目录) |
| `--env-mode <mode>` | 指定 env 模式来加载 `.env.[mode]` 文件,详见 [Rsbuild - Env 模式](https://rsbuild.rs/zh/guide/advanced/env-vars#env-模式) |
| `-h, --help` | 显示命令帮助 |
| `--lib <id>` | 指定运行命令的库(可重复,例如:`--lib esm --lib cjs`),查看 [lib.id](/config/lib/id) 了解如何获取或设置库的 ID |
| `-r, --root <root>` | 指定项目根目录,可以是绝对路径或者相对于 cwd 的路径 |

## rslib build

Expand Down
20 changes: 20 additions & 0 deletions website/docs/zh/guide/basic/configure-rslib.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,26 @@ Rslib CLI 通过 `--config` 选项来指定配置文件,可以设置为相对
rslib build -c rslib.prod.config.mjs
```

## 指定加载方式

当你使用 `.ts`, `.mts` 和 `.cts` 后缀的配置文件时,Rslib 会使用 [jiti](https://github.com/unjs/jiti) 来加载配置文件,提供 ESM 与 CommonJS 的互操作性,模块解析的行为与 Node.js 原生行为存在一定差异。

如果你使用的 JavaScript 运行时已经原生支持 TypeScript,可以使用 `--config-loader native` 选项来使用 Node.js 原生 loader 来加载配置文件。这可以保证模块解析的行为与 Node.js 原生行为一致,并且性能更好。

例如,Node.js 从 v22.6.0 开始已经原生支持 TypeScript,你可以如下命令来使用 Node.js 原生 loader 来加载配置文件:

```bash
# Node.js >= v22.18.0
# 不需要设置 --experimental-strip-types
npx rslib build --config-loader native

# Node.js v22.6.0 - v22.17.0
# 需要设置 --experimental-strip-types
NODE_OPTIONS="--experimental-strip-types" npx rslib build --config-loader native
```

> 详见 [Node.js - Running TypeScript Natively](https://nodejs.org/en/learn/typescript/run-natively#running-typescript-natively)。

## 使用环境变量

在配置文件中,你可以使用 `process.env.NODE_ENV` 等 Node.js 环境变量,来动态写入不同的配置:
Expand Down
Loading