> For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt.

# 从 0.x 升级到 v1

当前文档列出了从 Rslib 0.23 到 1.0 的所有不兼容更新，你可以参考此文档来迁移。

## Agent prompt

如果你正在使用 Coding Agent，可以复制以下 prompt 并发送给它：


For your Agent

从 0.x 升级到 v1

复制这个 prompt 并发送给你的 Coding Agent。

复制 Prompt

请阅读并遵循以下迁移指南，将当前项目从 Rslib 0.x 升级到 1.0：
https://rslib.rs/zh/guide/upgrade/v0-to-v1.md

## 升级 Rslib 到 v1

将 `@rslib/core` 升级到 1.0 版本：

```json title="package.json"
{
  "devDependencies": {
    "@rslib/core": "^1.0.0"
  }
}
```

## Rsbuild v2

Rslib v1 基于 Rsbuild v2，升级时可以通过 `peerDependencies` 检查项目中的 Rsbuild 插件是否支持 `@rsbuild/core` v2。推荐使用 [Taze](https://github.com/antfu-collective/taze) 将项目中的 Rsbuild 插件升级到最新版本：

```bash
# 升级当前目录中的 Rsbuild 插件
npx taze major --include "/rsbuild/" -w

# 或递归升级整个 monorepo 中的 Rsbuild 插件
npx taze major --include "/rsbuild/" -w -r
```

如果项目直接使用了 Rsbuild 配置或 JavaScript API，可以参考 [Rsbuild v2 升级指南](https://rsbuild.rs/zh/guide/upgrade/v1-to-v2) 了解相关变更。

## 默认语法目标更新

当 [output.target](/zh/config/rsbuild/output.md#outputtarget) 为 `'node'` 且未配置 [lib.syntax](/zh/config/lib/syntax.md) 时，Rslib v1 会尝试根据 `package.json#engines.node` 推断语法目标。

例如，以下 `engines.node`：

```json title="package.json"
{
  "engines": {
    "node": "^20.19.0 || >=22.12.0"
  }
}
```

Rslib 会将其解析为以下语法目标：

```ts title="rslib.config.ts"
export default {
  lib: [
    {
      syntax: ['node >= 20.19.0'],
    },
  ],
};
```

如果 `engines.node` 不存在或无法推断出最低版本，Rslib 会继续使用 `'esnext'`。

显式配置的 [lib.syntax](/zh/config/lib/syntax.md) 优先级高于自动推断，因此已有配置不会受到影响，也可以通过它覆盖根据 `engines.node` 推断出的目标。

此外，Rslib v1 调整了 `es2023` 和 `es2024` 的 Browserslist 基线，并新增了 `es2025`：

| `lib.syntax` | Rslib v0.x                                                  | Rslib v1                                                   |
| ------------ | ----------------------------------------------------------- | ---------------------------------------------------------- |
| `es2023`     | Chrome / Edge 94、Firefox 93、Safari / iOS 16.4、Node.js 16.11 | Chrome / Edge 110、Firefox 115、Safari / iOS 17、Node.js 20   |
| `es2024`     | 与 `esnext` 相同，使用动态的最新浏览器或 Node.js 版本                        | Chrome / Edge 112、Firefox 116、Safari / iOS 17、Node.js 20   |
| `es2025`     | 不支持                                                         | Chrome / Edge 126、Firefox 132、Safari / iOS 17.4、Node.js 23 |

这些配置仅控制 JavaScript 和 CSS 的语法降级，不会为目标环境缺失的运行时 API 注入 polyfill。新基线对 JavaScript 降级的实际影响较小，主要会使 Lightning CSS 输出更现代的 CSS。

如果新的基线符合预期，则无需调整。如果需要保留 Rslib v0.x 的语法目标行为：

- 项目原来使用 `es2023`，并且需要保留之前较保守的兼容范围：

  ```diff title="rslib.config.ts"
  export default {
    lib: [
      {
  -      syntax: 'es2023',
  +      syntax: 'es2022',
      },
    ],
  };
  ```

- 项目原来使用 `es2024`，并且需要继续使用动态的 Browserslist 目标：

  ```diff title="rslib.config.ts"
  export default {
    lib: [
      {
  -      syntax: 'es2024',
  +      syntax: 'esnext',
      },
    ],
  };
  ```

## 默认 `externalsType` 更新

对于 ESM 产物（[`format: 'esm'`](/zh/config/lib/format.md)），Rslib v1 将 Rspack 的默认 [`externalsType: 'module-import'`](https://rspack.rs/zh/config/externals#externalstypemodule-import) 调整为 [`externalsType: 'modern-module'`](https://rspack.rs/zh/config/externals#externalstypemodern-module)：

| 源码中的引用方式                               | Rslib v0.x     | Rslib v1                |
| -------------------------------------- | -------------- | ----------------------- |
| 静态 `import`                            | 输出为 ESM import | 输出为 ESM import          |
| 动态 `import()`                          | 保持动态导入         | 保持动态导入                  |
| CommonJS `require()`（`target: 'node'`） | 输出为 ESM import | 使用 `createRequire()` 加载 |
| CommonJS `require()`（`target: 'web'`）  | 输出为 ESM import | 保留 `require()`          |

这项变化只影响在未显式设置 `externalsType` 时，通过 `require()` 加载的外部 CommonJS 模块，包括通过 [lib.autoExternal](/zh/config/lib/auto-external.md)、[output.autoExternal](/zh/config/rsbuild/output.md#outputautoexternal)、[output.externals](/zh/config/rsbuild/output.md#outputexternals) 外部化的依赖，以及 `target: 'node'` 下自动外部化的 Node.js 内置模块。通过 ESM import 加载的 external 行为不变，通常不需要调整。

需要注意的是，如果产物中包含通过 `createRequire()` 加载的 external，并且该产物还会被再次打包，消费方的打包器需要能够静态分析这种调用。Rsbuild / Rspack 项目可以开启 [`module.parser.javascript.createRequire`](https://rspack.rs/zh/config/module-parser#javascriptcreaterequire)。如果模块加载语义允许，也可以考虑将源码中的 CommonJS `require()` 改为 ESM import。

如果只需要让某个依赖保留 Rslib v0.x 的行为，并且确认该依赖适用 ESM import 的加载语义，可以在 [output.externals](/zh/config/rsbuild/output.md#outputexternals) 中使用 `${externalsType} ${libraryName}` 语法，将该依赖指定为 `module-import`：

```ts title="rslib.config.ts"
export default {
  lib: [
    {
      output: {
        externals: {
          'some-package': 'module-import some-package',
        },
      },
    },
  ],
};
```

如果需要保留所有依赖在 Rslib v0.x 中的行为，可以通过 [tools.rspack](/zh/config/rsbuild/tools.md#toolsrspack) 将 `externalsType` 设置为 `module-import`：

```ts title="rslib.config.ts"
export default {
  lib: [
    {
      tools: {
        rspack(config) {
          config.externalsType = 'module-import';
        },
      },
    },
  ],
};
```

## 默认环境变量处理更新

在 Rslib v0.x 中，以下 [Rsbuild 默认环境变量](https://rsbuild.rs/zh/guide/advanced/env-vars#默认环境变量) 会在构建时被替换为指定的值：

- `import.meta.env.MODE`
- `import.meta.env.DEV`
- `import.meta.env.PROD`
- `import.meta.env.SSR`
- `import.meta.env.BASE_URL`
- `import.meta.env.ASSET_PREFIX`
- `process.env.BASE_URL`
- `process.env.ASSET_PREFIX`

Rslib v1 更改了这些变量在 [format](/zh/config/lib/format.md) 为 `'esm'` 和 `'cjs'` 时的处理方式：

| 产物格式 | Rslib v0.x | Rslib v1                                                                                        |
| ---- | ---------- | ----------------------------------------------------------------------------------------------- |
| esm  | 构建时替换      | `import.meta.env.*`、`process.env.BASE_URL` 和 `process.env.ASSET_PREFIX` 在构建产物中保留                |
| cjs  | 构建时替换      | `import.meta.env` 被替换为 `undefined`；`process.env.BASE_URL` 和 `process.env.ASSET_PREFIX` 在构建产物中保留 |

有关 Rslib v1 的完整环境变量处理行为，请参考 [环境变量](/zh/guide/advanced/env-vars.md)。

如果项目依赖 Rslib v0.x 的构建时替换行为，可以通过 [source.define](/zh/config/rsbuild/source.md#sourcedefine) 显式定义实际使用的变量，以恢复原有行为。如果需要在 CJS 产物中使用 `import.meta.env.*`，也需要显式定义对应的变量：

```ts title="rslib.config.ts"
export default {
  source: {
    define: {
      'import.meta.env.MODE': JSON.stringify('production'),
      'process.env.BASE_URL': JSON.stringify('/'),
      'process.env.ASSET_PREFIX': JSON.stringify(''),
    },
  },
};
```

## 资源模块处理更新

Rslib v1 调整了 ESM 产物（[`format: 'esm'`](/zh/config/lib/format.md)）中通过 `new URL()` 引用的静态资源、Web Workers 和 Wasm 模块的处理方式。

### `new URL()` 静态资源

Rslib v1 会在构建 ESM 产物时将可静态分析的 `new URL()` 引用作为静态资源处理。以引用 `logo.svg` 为例：

```ts title="src/index.ts"
const logo = new URL('./assets/logo.svg', import.meta.url);
```

对于项目源码，Rslib v0.x 会原样保留该表达式，且不会输出 `logo.svg`。Rslib v1 则会输出该文件，并将 `new URL()` 中的路径改写为指向该资源文件的相对路径。

```js title="dist/index.js"
const logo = new URL('./static/svg/logo.svg', import.meta.url);
```

对于被打包到产物中的三方依赖，Rslib v0.x 会将 `new URL()` 中的资源路径改写为模块引用，并在产物中注入用于加载该模块和计算基准 URL 的运行时代码。Rslib v1 则会采用与项目源码相同的处理方式，输出引用的资源，并将 `new URL()` 中的路径改写为指向该资源文件的相对路径。

如果项目原先通过 [output.copy](/zh/config/rsbuild/output.md#outputcopy) 配置或脚本复制这些资源，且升级后这些资源会由 Rslib 根据 `new URL()` 引用输出，应移除相应配置或脚本，避免重复输出。在 bundleless 模式（[`bundle: false`](/zh/config/lib/bundle.md)）下，如果 [source.entry](/zh/config/rsbuild/source.md#sourceentry) 也会匹配这些资源，还应将它们排除，避免为同一文件额外生成 JavaScript 入口。

如果需要跳过 Rslib 对 `new URL()` 引用的静态资源处理，可以根据作用范围选择以下方式，详情可以参考 [跳过 `new URL()` 处理](/zh/guide/advanced/static-assets.md#跳过-new-url-处理)。

- **跳过单个引用**：在 `new URL()` 的第一个参数前添加 [rspackIgnore](https://rspack.rs/zh/api/runtime-api/module-methods#rspackignore) 注释。

  ```ts title="src/index.ts"
  const logo = new URL(
    /* rspackIgnore: true */ './assets/logo.svg',
    import.meta.url,
  );
  ```

- **跳过所有引用**：通过 [tools.bundlerChain](/zh/config/rsbuild/tools.md#toolsbundlerchain) 将 `rslib:new-url` 规则中的 `url` parser 选项设置为 `false`。

  ```ts title="rslib.config.ts"
  import { defineConfig } from '@rslib/core';

  export default defineConfig({
    tools: {
      bundlerChain(chain) {
        chain.module.rule('rslib:new-url').parser({
          url: false,
        });
      },
    },
  });
  ```

此外，Rslib 的默认处理要求 `new URL()` 的引用目标在构建时能够解析为现有源文件，目录或仅在构建产物中存在的文件无法作为静态资源处理。例如：

```ts title="src/index.ts"
const currentDirectory = new URL('.', import.meta.url);
const generatedFile = new URL('./generated.js', import.meta.url);
```

对于这类引用，可以使用上述方式跳过 `new URL()` 处理。如果这些引用只是为了在 Node.js 中获取文件系统路径，也可以通过修改源码，改用 Node.js 的 `path` 和 `url` API：

```ts title="src/index.ts"
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const currentDirectory = path.dirname(fileURLToPath(import.meta.url));
const generatedFile = path.join(currentDirectory, 'generated.js');
```

更多详情请参考 [静态资源 - `new URL` 引用](/zh/guide/advanced/static-assets.md#new-url-引用)。

### Web Workers

构建 ESM 产物时，Rslib v1 会解析 `new Worker(new URL(...))`，并将其中引用的本地脚本作为 Worker 入口处理。以 `worker.ts` 为例：

```ts title="src/index.ts"
new Worker(new URL('./worker.ts', import.meta.url));
```

Rslib v0.x 会原样保留该表达式，不会根据这条引用构建 `worker.ts`。Rslib v1 则会构建 Worker 及其依赖，将 URL 重写为对应的产物路径，并自动添加 `type: 'module'`：

```js title="dist/index.js"
new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
});
```

如果项目此前将 Worker 源文件配置为独立入口，并在源码中引用预期生成的 `.js` 文件，升级后可以移除相应入口，改为直接引用 Worker 源文件：

```diff title="rslib.config.ts"
 export default {
   source: {
     entry: {
       index: './src/index.ts',
-      worker: './src/worker.ts',
     },
   },
 };
```

```diff title="src/index.ts"
-new Worker(new URL('./worker.js', import.meta.url));
+new Worker(new URL('./worker.ts', import.meta.url));
```

更多详情请参考 [Web Workers](/zh/guide/advanced/web-workers.md)。

### Wasm

Rslib v1 为 ESM 产物中的 Wasm 模块提供了两种输出模式：

- [`compile` 模式](/zh/guide/advanced/wasm.md#compile-模式)：Rslib 会生成加载和实例化 Wasm 模块所需的 JavaScript 代码，并输出带 hash 的 `.wasm` 文件。
- [`preserve` 模式](/zh/guide/advanced/wasm.md#preserve-模式)：JavaScript 中的 `.wasm` import 会被保留，`.wasm` 文件则沿用原文件名和相对目录输出，交由支持 [WebAssembly ESM Integration](https://github.com/WebAssembly/esm-integration) 的下游构建工具或目标运行时处理。

在 [bundleless 模式](/zh/config/lib/bundle.md) 下，Rslib v0.x 会生成加载和实例化 Wasm 模块所需的 JavaScript 代码，Rslib v1 则默认使用 `preserve` 模式，在 JavaScript 中保留 `.wasm` import。如需改用 `compile` 模式，可以配置 [`wasm.mode`](/zh/config/lib/wasm.md#wasmmode)：

```ts title="rslib.config.ts"
export default {
  lib: [
    {
      format: 'esm',
      bundle: false,
      wasm: {
        mode: 'compile',
      },
    },
  ],
};
```

[bundle 模式](/zh/config/lib/bundle.md) 下的 Wasm 处理行为保持不变。

更多详情请参考 [Wasm - 输出模式](/zh/guide/advanced/wasm.md#输出模式)。

## `@typescript/native-preview` 支持调整

在 Rslib v0.x 中，开启 [dts.tsgo](/zh/config/lib/dts.md#dtstsgo) 后，Rslib 会自动加载 `@typescript/native-preview` 来生成类型声明文件。

Rslib v1 默认不会加载 `@typescript/native-preview`，而是从项目根目录解析 `typescript`，并根据解析到的版本选择类型声明生成方式。检测到 TypeScript 7+ 时，Rslib 会自动启用 `dts.tsgo`。

如果需要继续使用 `@typescript/native-preview`，可以通过 [dts.typescriptPath](/zh/config/lib/dts.md#dtstypescriptpath) 显式指定它的模块入口：

```ts title="rslib.config.ts"
import { fileURLToPath } from 'node:url';

export default {
  lib: [
    {
      dts: {
        typescriptPath: fileURLToPath(
          import.meta.resolve('@typescript/native-preview'),
        ),
      },
    },
  ],
};
```

## 临时类型声明目录调整

在类型打包过程中，Rslib 会生成临时类型声明文件。Rslib v1 对这些文件所在的目录进行了调整，由 `.rslib/declarations` 改为 `.rstack/declarations`。升级后，可以安全删除旧的 `.rslib` 目录。

## Node.js 模板更新

Rslib v1 不再提供 ESM/CJS 双格式的 Node.js 模板，仅提供纯 ESM 模板。创建项目时，`--template` 参数需要按下表更新：

| Rslib v0.x `--template` 参数 | Rslib v1 `--template` 参数 |
| -------------------------- | ------------------------ |
| `node-esm`                 | `node`                   |
| `node-esm-js`              | `node-js`                |
| `node-esm-ts`              | `node-ts`                |
| `node-dual`                | 不再支持                     |
| `node-dual-js`             | 不再支持                     |
| `node-dual-ts`             | 不再支持                     |

例如，使用原纯 ESM 模板的命令需要按如下方式更新：

```diff
-npx create-rslib my-project --template node-esm
+npx create-rslib my-project --template node
```

此外，新模板默认将 `engines.node` 设置为 `^20.19.0 || >=22.12.0`，并且不再显式配置 `lib.syntax`。Rslib 会根据 `engines.node` 自动推断 `lib.syntax`，详情请参考[默认语法目标更新](#默认语法目标更新)。

`engines.node` 覆盖的 Node.js 版本均支持 `require(ESM)`，因此原有的 CommonJS 消费者现在可以直接通过 `require()` 加载纯 ESM 包，前提是入口及其依赖不使用顶层 `await`：

```js
const packageExports = require('pure-esm-package');
```

如果仍需要 ESM/CJS 双格式模板，可以通过以下命令使用旧版生成器创建：

```bash
npx -y create-rslib@0.23.2 my-project --template node-dual
```

## 配置

### 默认开启 `redirect.dts.extension`

Rslib v1 默认开启了 [redirect.dts.extension](/zh/config/lib/redirect.md#redirectdtsextension)，在生成 bundleless 类型声明文件时，导入路径会自动补全或替换为可以解析到相应类型声明文件的 JavaScript 文件扩展名。

例如，当导入路径对应 `foo.d.ts` 时，生成结果如下：

```diff title="dist/index.d.ts"
-export type { Foo } from './foo';
+export type { Foo } from './foo.js';
```

如果你的消费工具依赖不带扩展名的类型导入路径，或由其他工具负责重写扩展名，可以恢复 Rslib 0.x 的行为：

```ts title="rslib.config.ts"
export default {
  lib: [
    {
      redirect: {
        dts: {
          extension: false,
        },
      },
    },
  ],
};
```

如果你同时配置了 `compilerOptions.paths` 或 [dts.alias](/zh/config/lib/dts.md#dtsalias)，请检查映射后的类型导入路径是否需要直接指向具体的类型声明入口，详情请参考 [redirect.dts.extension](/zh/config/lib/redirect.md#注意事项)。

### 迁移 `lib.autoExternal`

[lib.autoExternal](/zh/config/lib/auto-external.md) 已在 Rslib v1 中废弃，但暂未移除，仍可继续使用。

我们推荐使用 Rsbuild 的 [output.autoExternal](/zh/config/rsbuild/output.md#outputautoexternal) 配置替代它：

```diff title="rslib.config.ts"
 export default {
   lib: [
     {
-      autoExternal: false,
+      output: {
+        autoExternal: false,
+      },
     },
   ],
 };
```

### 移除 `experiments.advancedEsm`

`experiments.advancedEsm` 选项已被移除。

该选项原本用于生成对静态分析更友好并支持代码分割的 ESM 产物。但在 Rslib v1 中，这种 ESM 输出已成为默认行为，因此该选项不再需要。

```diff title="rslib.config.ts"
 export default {
   lib: [
     {
-      experiments: {
-        advancedEsm: true,
-      },
     },
   ],
 };
```

## JavaScript API

- [RslibConfig](/zh/api/javascript-api/types.md#rslibconfig) 中 `lib` 的类型从 `LibConfig[]` 变为 `LibConfig[] | undefined`。省略 `lib` 时，行为等同于配置 `lib: [{}]`。
- [`rslib.inspectConfig()`](/zh/api/javascript-api/instance.md#rslibinspectconfig) 的 `mode` 选项移除了无效的 `'none'` 值。未设置 `mode` 时，现在会根据 `process.env.NODE_ENV` 推断：当 `NODE_ENV` 为 `'development'` 时，`mode` 为 `'development'`，否则为 `'production'`。当 `mode` 为 `'development'` 时，`rslib.inspectConfig()` 现在仅会输出 `format: 'mf'` 的库配置。
