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

# Experiments

该选项允许用户开启和尝试一些实验性的功能。

- **类型：** `object`

:::tip
在 minor release 中，Rspack 可能对这些实验性特性的 public API 做一些调整，并在更新日志中对这些变动进行详细的说明。因此，如果你使用了实验性特性，请留意 minor 版本的更新日志。
:::

## experiments.asyncWebAssembly

- **类型：** `boolean`
- **默认值：** `true`

支持基于[新规范](https://github.com/WebAssembly/esm-integration)的 WebAssembly，这使 WebAssembly 模块成为异步模块。

```js title="rspack.config.mjs"
export default {
  experiments: {
    asyncWebAssembly: true,
  },
};
```

## experiments.buildHttp


[Added in v1.3.0](https://github.com/web-infra-dev/rspack/releases/tag/v1.3.0)

- **类型：** `HttpUriOptions`
- **默认值：** `undefined`

```ts
type HttpUriOptions = {
  /**
   * A list of allowed URIs
   */
  allowedUris: (string | RegExp)[];
  /**
   * Define the location to store the lockfile
   */
  lockfileLocation?: string;
  /**
   * Define the location for caching remote resources
   */
  cacheLocation?: string | false;
  /**
   * Detect changes to remote resources and upgrade them automatically
   * @default false
   */
  upgrade?: boolean;
  /**
   * Freeze the remote resources and lockfile
   * @default true in production mode, false otherwise
   */
  frozen?: boolean;
  /**
   * Custom http client
   */
  httpClient?: (
    url: string,
    headers: Record<string, string>,
  ) => Promise<{
    status: number;
    headers: Record<string, string>;
    body: Buffer;
  }>;
};
```

启用此功能后，Rspack 可以构建以 `http(s):` 协议开头的远程资源。Rspack 会将资源下载到本地，然后再进行打包。

`allowedUris` 中的字符串必须是有效的绝对 URL。Rspack 会先规范化请求 URL 和各个字符串规则，再比较前缀。例如，`'https://example.com'` 会被规范化为 `'https://example.com/'`。无效字符串（如 `'https://'`）会被忽略。正则表达式匹配的是规范化后的 URL；如果你希望允许任意 HTTPS URL，可以使用 `/^https:\/\//`。重定向目标也必须匹配 `allowedUris`。

默认情况下，Rspack 会在 [context](/zh/config/context.md) 文件夹下生成 `rspack.lock` 和 `rspack.lock.data` 分别作为 Lockfile 和缓存的位置，你也可以通过 `lockfileLocation` 和 `cacheLocation` 进行配置。

:::note
你应该将 `lockfileLocation` 和 `cacheLocation` 的文件提交到版本控制系统中，以便生产构建使用缓存内容。
:::

Rspack 会根据 lockfile 中记录的 SHA-512 校验缓存内容。`frozen` 在生产模式下默认为 `true`，其他模式下默认为 `false`。冻结时，缺少锁定条目、缓存内容损坏、缓存文件缺失，以及资源内容、最终 URL 或内容类型发生变化，都会导致构建报错。此时不会更新 lockfile 及其内容缓存。即使设置了 `cacheLocation: false`，下载的内容也必须与锁定条目一致。

旧版 lockfile 可能只在重定向的最终 URL 下记录条目。如果原始 URL 没有条目，冻结构建会发起网络请求，沿允许的重定向查找已有锁定条目，然后校验其内容，不会重写 lockfile 或缓存。未能到达锁定资源的导入仍会报错。如果原始 URL 已有条目，则始终以该条目为准。

首次生成 lockfile 和缓存时，请运行开发模式构建，或显式设置 `frozen: false`。若需检查远程更新，还应设置 `upgrade: true`，随后审查并提交文件变化。`upgrade: false` 表示优先使用缓存，不代表需要下载内容时禁止更新 lockfile。与 webpack 一致，非冻结构建也可以更新 lockfile，以接受本地修改过的缓存文件。

记录为 `"no-cache"` 或 `"ignore"` 的资源不会锁定下载内容，冻结模式下也一样。完整性检查依赖可信的 lockfile，无法验证首次下载的真实性。为防止 Git 转换缓存文件的换行符，请在 `.gitattributes` 中加入 `**/*rspack.lock.data/** -text`；使用自定义缓存位置时，请调整匹配路径。

示例：

```js title="rspack.config.mjs"
import path from 'node:path';

export default {
  experiments: {
    buildHttp: {
      allowedUris: ['https://example.com/'],
      lockfileLocation: path.join(import.meta.dirname, 'my_project.lock'),
      cacheLocation: path.join(import.meta.dirname, 'my_project.lock.data'),
    },
  },
};
```

启用此功能后，你可以直接从网址导入模块：

```js
// Import from a remote URL
import { something } from 'https://example.com/module.js';

// Or import assets
import imageUrl from 'https://example.com/image.png';
```

## experiments.deferImport


[Added in v1.6.0](https://github.com/web-infra-dev/rspack/releases/tag/v1.6.0)

- **类型：** `boolean`
- **默认值：** `false`

开启后 Rspack 会支持打包 [Deferred Imports Evaluation](https://github.com/tc39/proposal-defer-import-eval) 提案，该功能允许延迟模块的执行直到首次使用。Rspack 支持 `import defer * as ns from "./module"` 和 `import.defer()` 两种语法。

```js title="rspack.config.mjs"
export default {
  experiments: {
    deferImport: true,
  },
};
```

:::info 已知的限制
目前在使用 `output.module: true` 时，对 external 模块使用 `defer import` 语法会被编译为普通的 `import` 语法。

例如，当 `jquery` 配置为 external 时：

```js
import defer * as $ from 'jquery';
```

将会生成：

```js
import * as __rspack_external_jquery from 'jquery';
```

这是因为目前尚未有运行时支持 `defer import` 语法。未来当更多运行时支持该语法后，Rspack 将会根据 target 配置决定是否保留 `defer import` 语法，生成如下代码：

```js
import defer * as __rspack_external_jquery from 'jquery';
```

:::

## experiments.sourceImport


[Added in v2.0.8](https://github.com/web-infra-dev/rspack/releases/tag/v2.0.8)

Stability: Experimental

- **类型：** `boolean`
- **默认值：** `false`

开启对 TC39 [Source Phase Imports](https://github.com/tc39/proposal-source-phase-imports) 提案的支持。

Source phase import 允许在模块执行前导入模块。Rspack 当前主要面向 WebAssembly 模块提供该能力：以 source phase 导入 `.wasm` 模块时，返回的是编译后的 [`WebAssembly.Module`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module)，你可以自行实例化它、使用不同 imports 多次实例化，或将它传递给 worker。

启用 `experiments.sourceImport`：

```js title="rspack.config.mjs"
export default {
  experiments: {
    sourceImport: true,
  },
};
```

你可以使用静态的 source-phase 语法：

```js
import source wasmModule from './module.wasm';

const instance = await WebAssembly.instantiate(wasmModule, {
  // imports...
});
```

也可以使用动态语法：

```js
const wasmModule = await import.source('./module.wasm');
const instance = await WebAssembly.instantiate(wasmModule);
```

:::note
普通 WebAssembly 导入会由 Rspack 实例化模块并暴露其导出；source phase 导入会返回编译后的 `WebAssembly.Module`，需要你的代码自行调用 `WebAssembly.instantiate`。
:::

## experiments.futureDefaults

- **类型：** `boolean`
- **默认值：** `false`

使用下一个主版本 Rspack 的默认值，并在任何有问题的地方显示警告。

```js title="rspack.config.mjs"
export default {
  experiments: {
    futureDefaults: true,
  },
};
```

## experiments.nativeWatcher


[Added in v1.4.7](https://github.com/web-infra-dev/rspack/releases/tag/v1.4.7)

- **类型：** `boolean`
- **默认值：** `false`

默认情况下，Rspack 使用 Watchpack 来监听文件变化，这在大多数情况下都能正常工作，但在某些特定的环境下可能会出现问题。
例如在大量文件变化时，Watchpack 可能会出现性能问题, 更多详情请参考 [Watchpack issue #223](https://github.com/webpack/watchpack/issues/223)。

如果你使用默认的 watcher 出现性能问题，可以尝试启用 `nativeWatcher`。

启用 `nativeWatcher` 后，Rspack 将使用 Rust Native 文件系统监听文件变化，实现增量监听文件变更能力，这提供更好的性能和稳定性。

```js title="rspack.config.mjs"
export default {
  watchOptions: {
    // Other watch options...
  },
  experiments: {
    nativeWatcher: true,
  },
};
```

## experiments.pureFunctions


[Added in v2.0.0](https://github.com/web-infra-dev/rspack/releases/tag/v2.0.0)

- **类型：** `boolean`
- **默认值：** 生产模式下为 `true`，其他模式下为 `false`

开启跨模块的无副作用函数调用优化，包括 `/*#__NO_SIDE_EFFECTS__*/` 注解和 [`module.parser.javascript.pureFunctions`](/zh/config/module-parser.md#javascriptpurefunctions) 配置。被注解或用户配置标记的无副作用函数如果没有被真正使用到，则不会被打包进产物。

更多背景可参考 [pureFunctions](/zh/guide/optimization/tree-shaking.md#purefunctions) 和 [NO\_SIDE\_EFFECTS 注解](/zh/guide/optimization/tree-shaking.md#no_side_effects-注解)。

该能力在生产模式下默认开启。若要关闭 pure function 分析，可将该选项设为 `false`。若要手动为命中的模块标记标识符 —— 既可以是第三方库中的导出函数，也可以是你自己代码中的 import 或本地声明 —— 推荐通过 `module.rules[i].parser` 来配置 [`module.parser.javascript.pureFunctions`](/zh/config/module-parser.md#javascriptpurefunctions)，这样规则只会作用于目标模块。

```js title="rspack.config.mjs"
export default {
  experiments: {
    pureFunctions: true,
  },
  module: {
    rules: [
      {
        test: /node_modules\/some-library\/index\.js$/,
        parser: {
          pureFunctions: ['isString'],
        },
      },
    ],
  },
};
```

:::warning
这个选项依赖 `optimization.sideEffects`。如果你关闭了 [`optimization.sideEffects`](/zh/config/optimization.md#optimizationsideeffects)，pure function 相关提示将不会被分析。
:::

## experiments.runtimeMode


[Added in v2.2.0](https://github.com/web-infra-dev/rspack/releases/tag/v2.2.0)

- **类型：** `'webpack' | 'rspack'`
- **默认值：** `'webpack'`

将 `experiments.runtimeMode` 设置为 `'rspack'` 会启用 Rspack 的实验性 runtime 产物。该产物模式仍在开发中，请谨慎使用。目前，它在 [`output.module`](/zh/config/output.md#outputmodule) 为 `true`，且 [`output.library.type`](/zh/config/output.md#outputlibrarytype) 为 `'modern-module'` 时能够精简产物。在这种情况下，runtime 不再只导出一个挂载了多个辅助函数的 `__webpack_require__`，而是将加载函数、模块工厂和辅助函数分别导出为具名 ESM 绑定，让每个产物 chunk 只需导入实际使用的绑定。

### 示例

```js title="rspack.config.mjs"
export default {
  experiments: {
    runtimeMode: 'rspack',
  },
  output: {
    module: true,
    library: {
      type: 'modern-module',
    },
  },
  optimization: {
    runtimeChunk: 'single',
  },
};
```

生成的 runtime 及使用它的 chunk 会采用如下组织方式（代码经过简化）：


**runtimeMode: 'webpack'**

```js
// runtime.js
var __webpack_modules__ = {};
function __webpack_require__(moduleId) {
  /* ... */
}
__webpack_require__.m = __webpack_modules__;
__webpack_require__.n = (module) => {
  /* ... */
};

export { __webpack_require__ };

// main.js
import { __webpack_require__ } from './runtime.js';

const value = __webpack_require__(moduleId);
const getDefault = __webpack_require__.n(value);
```


**runtimeMode: 'rspack'**

```js
// runtime.js
var modules = {};
function rspackRequire(moduleId) {
  /* ... */
}
var moduleFactories = modules;
var compatGetDefaultExport = (module) => {
  /* ... */
};

export { rspackRequire, moduleFactories, compatGetDefaultExport };

// main.js
import { rspackRequire, compatGetDefaultExport } from './runtime.js';

const value = rspackRequire(moduleId);
const getDefault = compatGetDefaultExport(value);
```


## experiments.useInputFileSystem


[Added in v1.3.14](https://github.com/web-infra-dev/rspack/releases/tag/v1.3.14)

- **类型：** `false | RegExp[]`
- **默认值：** `false`

默认情况下，Rspack 使用原生文件系统从磁盘读取文件。
但你也可以通过更换 inputFileSystem，使用其他类型的文件系统。例如，可以用 memfs 替代默认文件系统来支持虚拟模块。

不过，由于调用 Node.js 实现的文件系统存在性能开销，会显著拖慢 Rspack 的运行速度。
因此，Rspack 提供了 `useInputFileSystem` 配置项，用于控制是使用原生文件系统还是自定义的 inputFileSystem。
一般项目中，只有少量文件需要通过自定义文件系统访问，合理配置 `experiments.useInputFileSystem` 可以确保 Rspack 高效运行。

下面的例子演示了如何替换默认的 inputFileSystem 为一个自定义的文件系统，只要自定义文件系统满足 [`InputFileSystem`](/zh/api/javascript-api/compiler.md#inputfilesystem-1) 的接口定义。
更多细节参考[测试用例](https://github.com/web-infra-dev/rspack/tree/main/tests/rspack-test/configCases/input-file-system/rspack.config.js)。

```js title="rspack.config.mjs"
export default {
  entry: {
    index: './virtual_index.js',
  },
  plugins: [
    {
      apply: (compiler) => {
        compiler.hooks.beforeCompile.tap('SimpleInputFileSystem', () => {
          compiler.inputFileSystem = {
            readFile(path, cb) {
              cb(null, `// the file content`);
            },
            stat(p, cb) {
              cb(null, fsState);
            },
          };
        });
      },
    },
  ],
  experiments: {
    useInputFileSystem: [/virtual_.*\.js/],
  },
};
```

:::info 注意
只有在 `compiler.run` 执行前替换的 `compiler.inputFileSystem` 才会生效；在 `compiler.run` 执行后替换将不会生效。
:::

### 配合 webpack-virtual-modules 使用

例子：

```js title="rspack.config.mjs"
import VirtualModulesPlugin from 'webpack-virtual-modules';

const virtualModules = new VirtualModulesPlugin({
  'virtual-entry.js': `
    import "./src/another-virtual.js";
    import "./src/disk-file.js";
    `,
  'src/another-virtual.js': 'export default 42;',
});

export default {
  entry: './virtual-entry.js',
  plugins: [virtualModules],
  experiments: {
    useInputFileSystem: [/.*virtual.*\.js$/],
  },
};
```

当访问 `virtual-entry.js` 和 `src/another-virtual.js` 时，它们匹配了 `experiments.useInputFileSystem` 中的正则规则，Rspack 会通过 `VirtualModulesPlugin` 包装的输入文件系统读取它们；而像 `src/disk-file.js`，则会使用原生文件系统读取。


本页改编自 [webpack 文档](https://webpack.js.org/configuration/experiments/)，遵循 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)，且已作修改。

