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

# Devtool

`devtool` 用于控制 Rspack 为输出代码生成哪些调试信息，包括是否生成 source map，以及 source map 的输出方式和映射精度。不同的配置会影响浏览器开发工具和错误监控工具将打包代码还原到原始源码的能力，也会影响构建速度以及源码暴露风险。

- **类型：**

```ts
type Devtool = string | false;
```

- **默认值：** development 模式为 `cheap-module-source-map`，production 模式为 `false`

## 推荐配置

以下示例通过 `process.env.NODE_ENV` 区分开发和生产环境。

### 仅开发环境启用

如果仅在开发阶段需要调试信息，生产环境不需要生成 source map，使用以下配置：

```js title="rspack.config.mjs"
const isDev = process.env.NODE_ENV === 'development';

export default {
  devtool: isDev ? 'cheap-module-source-map' : false,
};
```

- **开发环境：** 使用 `cheap-module-source-map`，生成行级 source map，在调试精度和构建速度之间取得平衡。
- **生产环境：** 设为 `false`，不生成 source map，也不会增加 source map 的生成开销。

### 全部禁用

如果两个环境都不需要 source map，使用以下配置：

```js title="rspack.config.mjs"
export default {
  devtool: false,
};
```

该配置的构建开销最低，也不会输出 `.map` 文件。缺点是浏览器报错和生产错误堆栈只能指向打包后的代码，无法还原到原始源码。

### 全部启用

如果开发阶段需要快速的 source map，同时希望在生产环境获得完整的行列映射，使用以下配置：

```js title="rspack.config.mjs"
const isDev = process.env.NODE_ENV === 'development';

export default {
  devtool: isDev ? 'cheap-module-source-map' : 'source-map',
};
```

- **开发环境：** 使用构建速度更快的 `cheap-module-source-map`。
- **生产环境：** 使用 `source-map`，生成包含行列映射的独立 `.map` 文件，并在 bundle 中添加 `sourceMappingURL` 注释。只要 `.map` 文件可访问，浏览器开发工具就能自动加载它。该配置适合直接调试生产代码，但会增加构建时间，并可能向用户暴露源码。

### 生产环境隐藏引用

如果生产环境需要 source map 来还原错误堆栈，但不希望浏览器从 bundle 中自动发现它，使用以下配置：

```js title="rspack.config.mjs"
const isDev = process.env.NODE_ENV === 'development';

export default {
  devtool: isDev ? 'cheap-module-source-map' : 'hidden-source-map',
};
```

- **开发环境：** 使用构建速度更快的 `cheap-module-source-map`。
- **生产环境：** 使用 `hidden-source-map`，生成包含完整行列映射的独立 `.map` 文件，但不在 bundle 中添加 `//# sourceMappingURL` 注释。该配置适合将 source map 私下上传到错误监控服务，用于还原生产错误堆栈。

:::warning
`hidden-source-map` 只会移除 bundle 中的引用，并不会加密或保护 `.map` 文件。除非你明确希望公开源码，否则不要将生产环境的 `.map` 文件部署到可公开访问的 Web 服务器或 CDN；应将它们上传到受限的错误监控服务。
:::

## 常用值

下表比较了常用配置的映射精度、输出方式和适用场景。

| 值                         | 映射内容            | 输出方式                        | 适用场景              |
| ------------------------- | --------------- | --------------------------- | ----------------- |
| `cheap-module-source-map` | 原始源码，仅包含行映射     | 通常为独立的 `.map` 文件            | 平衡调试精度和构建速度的开发环境  |
| `cheap-source-map`        | 转换后的代码，仅包含行映射   | 通常为独立的 `.map` 文件            | 不需要映射回原始源码的开发环境   |
| `eval`                    | 仅提供模块名称，不能映射回源码 | 使用 `eval()` 包装每个模块          | 开发环境中仅需定位模块       |
| `eval-source-map`         | 原始源码，包含行列映射     | 每个模块的 map 内联到对应的 `eval()` 中 | 开发环境中需要精确调试       |
| `false`                   | 不生成 source map  | 无                           | 不需要调试信息           |
| `hidden-source-map`       | 原始源码，包含行列映射     | 独立的 `.map` 文件，bundle 中不包含引用 | 私下上传到错误监控服务       |
| `inline-source-map`       | 原始源码，包含行列映射     | 以 Data URL 的形式内联到 bundle 中  | 需要分发单个文件的开发或测试场景  |
| `nosources-source-map`    | 包含行列映射，但不包含源码内容 | 独立的 `.map` 文件，bundle 中包含引用  | 需要映射但不希望 map 包含源码 |
| `source-map`              | 原始源码，包含行列映射     | 独立的 `.map` 文件，bundle 中包含引用  | 需要直接调试生产代码        |

## 修饰符

不带修饰符的 `source-map` 会生成包含行列映射的独立 `.map` 文件，并在 bundle 中添加 `sourceMappingURL` 注释。你可以添加以下修饰符来改变生成方式、映射精度或 map 内容。

### `eval`

将每个模块包装在 `eval()` 中。当它与 `source-map` 组合为 `eval-source-map` 时，每个模块的 source map 会以 Data URL 的形式写入对应的 `eval()`，从而避免合并 chunk 级 source map，提升重新构建速度。该修饰符通常只用于开发环境。

单独使用 `devtool: 'eval'` 时不会生成 source map，而是通过 `//# sourceURL` 为每个模块提供可读的模块名称，只能定位到模块，不能映射回原始源码。

### `inline`

将 source map 以 Data URL 的形式内联到 bundle 中，不生成独立的 `.map` 文件，例如 `inline-source-map`。这便于传输单个文件，但会明显增大 bundle 体积。默认情况下，source map 还会把源码内容一并包含在 bundle 中；与 `nosources` 组合时除外。因此，该修饰符通常只用于开发或测试。

### `hidden`

生成独立的 `.map` 文件，但不在 bundle 中添加 `//# sourceMappingURL` 注释，例如 `hidden-source-map`。浏览器不会自动发现该文件，适合将 source map 私下上传到错误监控服务。它不会阻止用户直接访问已公开部署的 `.map` 文件。

### `nosources`

从 source map 中移除 `sourcesContent`，例如 `nosources-source-map`。map 仍然包含原始文件名、目录结构和映射信息，可以用于还原错误堆栈，但不能单独向开发工具提供原始源码内容。

### `cheap`

只生成行映射，不生成列映射，以减少 source map 的计算开销，例如 `cheap-source-map`。单独使用时会忽略 loader 提供的 source map，因此映射结果指向 loader 转换后的代码，而不是原始源码。

:::tip
在启用代码压缩的 production 构建中，使用 `cheap` 修饰符（如 `cheap-source-map` 或 `cheap-module-source-map`）时，可能不会生成 source map 文件，这是符合预期的。压缩后的代码通常只有一行，而 `cheap` 只提供行级映射，因此无法生成有实际价值的映射。关闭代码压缩时仍可能生成 `.map` 文件。
:::

### `module`

仅与 `cheap` 组合使用，例如 `cheap-module-source-map`。它会处理 loader 提供的 source map，将行映射还原到原始源码。与 `cheap-source-map` 相比，它的映射结果更准确，但计算开销也略高。不使用 `cheap` 时，`source-map` 默认就会处理 loader 的 source map，无需添加 `module`。

### `debugids`

`debugids` 基于 [TC39 Debug ID 提案](https://github.com/tc39/ecma426/blob/main/proposals/debug-id.md)，为 source map 添加 `debugId`。例如，使用 `source-map-debugids` 时，Rspack 还会在对应的输出资源中添加匹配的 `//# debugId` 注释，便于错误监控工具关联构建产物与 source map。

Rspack 会校验修饰符的顺序，格式必须为 `[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map[-debugids]`。其中 `inline`、`hidden` 和 `eval` 互斥，`module` 只能跟在 `cheap` 之后，`debugids` 位于末尾。

## 相关配置

- [`output.sourceMapFilename`](https://rspack.rs/zh/config/output.md#outputsourcemapfilename)：自定义独立 source map 文件的名称。
- [`output.devtoolModuleFilenameTemplate`](https://rspack.rs/zh/config/output.md#outputdevtoolmodulefilenametemplate)、[`output.devtoolFallbackModuleFilenameTemplate`](https://rspack.rs/zh/config/output.md#outputdevtoolfallbackmodulefilenametemplate) 和 [`output.devtoolNamespace`](https://rspack.rs/zh/config/output.md#outputdevtoolnamespace)：控制 source map 中的模块名称，并避免多个构建之间的名称冲突。
- [`rules[].extractSourceMap`](https://rspack.rs/zh/config/module-rules.md#rulesextractsourcemap)：从输入文件的 `sourceMappingURL` 注释中提取现有的 source map。

## 精细控制

`devtool` 只会为 JavaScript 和 CSS 输出资源（即文件名匹配 `/\.((c|m)?js|css)($|\?)/i` 的资源）生成 source map，与 webpack 一致。其他输出资源，例如通过 [`generator.binary: false`](https://rspack.rs/zh/config/module-generator.md#assetbinary) 输出的文本资源，不会被处理。如需为这些资源生成 source map，请使用 [SourceMapDevToolPlugin](https://rspack.rs/zh/plugins/source-map-dev-tool-plugin.md) 并设置匹配的 [`test`](https://rspack.rs/zh/plugins/source-map-dev-tool-plugin.md#test)。

如需更细粒度地控制 source map 的生成方式，将 `devtool` 设为 `false`，并改用 [SourceMapDevToolPlugin](https://rspack.rs/zh/plugins/source-map-dev-tool-plugin.md)；对于基于 `eval` 的 source map，改用 [EvalSourceMapDevToolPlugin](https://rspack.rs/zh/plugins/eval-source-map-dev-tool-plugin.md)。


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

