> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Manifest.json 编译与输出

> 把 manifest.json 作为入口与资源的唯一事实来源。Extension.js 会编译、重写路径并输出可直接加载的 manifest。

通过把 `manifest.json` 视为入口、资源与浏览器特定行为的唯一事实来源，让扩展构建保持可预测。

Extension.js 会编译你的 manifest，并过滤带浏览器前缀的字段。它会重写运行时路径，校验所引用的文件，并为每个目标浏览器生成可直接加载的 manifest。

## Manifest 能力

| 能力        | 你会得到什么                                     |
| --------- | ------------------------------------------ |
| 浏览器特定字段过滤 | 保留一份 manifest 文件，同时输出目标特定的产物               |
| 路径归一      | 自动解析为运行时安全的输出路径                            |
| 引用校验      | 当 HTML/脚本/CSS/JSON/图标文件缺失时尽早失败             |
| 目标产物      | 在 `dist/<browser>` 中为每个浏览器目标生成 manifest 产物 |

## Extension.js 从哪里读取 manifest

* `src/manifest.json`（存在时优先）
* 项目根目录下的 `manifest.json`

Extension.js 不会把 `public/manifest.json` 作为源 manifest。

当项目存在 `package.json` 时，Extension.js 会忽略 `public/manifest.json`。这可以防止被复制的静态资源覆盖 Extension.js 生成的 manifest。

## Extension.js 对它做了什么

在 dev/build 阶段，manifest 管线会：

1. 从你的源文件输出 manifest 资源。
2. 为当前激活的浏览器目标过滤带浏览器前缀的键。
3. 为扩展产物应用 manifest 覆盖/路径归一。
4. 校验所引用的文件（HTML/脚本/CSS/图标/JSON），缺失时尽早失败。

## 一份 manifest，多种浏览器

带浏览器前缀的键让你可以保留一份 manifest 文件，同时支持浏览器特定的行为：

* `chromium:*`、`chrome:*`、`edge:*`
* `firefox:*`、`gecko:*`

这些前缀既可用于顶层键，也可用于嵌套的 manifest 字段。

示例：

* `chromium:key`
* `background.firefox:scripts`
* `background.chromium:service_worker`

### 受支持的 manifest 字段

常见的与入口相关的字段包括：

| Manifest 字段                              | 期望的文件类型                |
| ---------------------------------------- | ---------------------- |
| `action.default_popup`                   | .html                  |
| `background.page`                        | .html                  |
| `background.service_worker`              | .js、.jsx、.ts、.tsx、.mjs |
| `browser_action.default_popup`           | .html                  |
| `chrome_url_overrides.bookmarks`         | .html                  |
| `chrome_url_overrides.history`           | .html                  |
| `chrome_url_overrides.newtab`            | .html                  |
| `content_scripts.js`                     | .js、.jsx、.ts、.tsx、.mjs |
| `content_scripts.css`                    | .css、.scss、.sass、.less |
| `declarative_net_request.rule_resources` | .json                  |
| `devtools_page`                          | .html                  |
| `icons`                                  | .png、.jpg 等其他图像格式      |
| `options_ui.page`                        | .html                  |
| `options_page`                           | .html                  |
| `page_action.default_popup`              | .html                  |
| `sandbox.pages`                          | .html                  |
| `side_panel.default_path`                | .html                  |
| `sidebar_action.default_panel`           | .html                  |
| `storage.managed_schema`                 | .json                  |
| `theme_icons`                            | .png、.jpg 等其他图像格式      |
| `user_scripts.api_script`                | .js、.jsx、.ts、.tsx、.mjs |
| `web_accessible_resources`               | .png、.jpg、.css、.js     |

## 权限设计

Manifest 也是扩展声明自身能力的地方。Extension.js 会编译 manifest，但你仍然需要良好的权限设计。

* 让 `permissions` 保持小而有意为之。
* 让 `host_permissions` 收窄到功能确实需要的范围。
* 在可能时，把非核心能力放进 `optional_permissions` 或 `optional_host_permissions`。
* 每当 content script 的匹配或 background 能力发生变化时，重新审视权限范围。

关于权限策略，参见 [权限与主机权限](/docs/implementation-guide/permissions-and-host-permissions)。

## 输出行为

当需要时，Extension.js 会把 manifest 路径重写为可预测的输出位置。两个重要的例子：

* `background.service_worker` 会变成 `background/service_worker.js`
* `side_panel.default_path` 会变成 `sidebar/index.html`

Extension.js 还会按 manifest 入口索引归一化 content script：

* `content_scripts/content-0.js`
* `content_scripts/content-0.css`

那些输出路径才是浏览器实际加载的内容。在编写时使用源路径，让 Extension.js 在输出时重写它们。

## 开发期行为

* 当 `manifest.json` 发生变化时，Extension.js 会重新编译并触发扩展的硬重载流程。
* 如果 manifest 入口结构发生变化（例如脚本列表变更），Extension.js 可能要求重启开发服务器。
* manifest 字段所引用的文件缺失会以聚焦于 manifest 的错误使编译失败。

### 变更结果矩阵

| Manifest 变更类型                             | 通常的结果           |
| ----------------------------------------- | --------------- |
| 修改非结构性的值（例如 descriptions/permissions 元数据） | 硬重载流程           |
| 修改仍能干净解析的资源路径值                            | 重新编译 + 硬重载流程    |
| 在 manifest 中新增/删除脚本或页面入口                  | 需要重启            |
| 引入不合法/缺失的被引用文件                            | 构建错误（先修复，再重新运行） |

## 最佳实践

* 让 manifest 路径相对于扩展的源/输出模型，仅在确实意指扩展输出根目录时才使用开头的 `/`。
* 使用带浏览器前缀的键，而不是为每个浏览器维护单独的 manifest 文件。
* 谨慎修改入口；在开发期新增/删除 manifest 脚本往往会改变重载语义。
* 把图标、JSON 资源和 content script 资源的校验作为持续集成（CI）的一部分，尽早发现路径回归。
* 不要把 `manifest.json` 放在 `public/` 下。

## 下一步

* 在 [dev 更新行为](/docs/workflows/dev-update-behavior) 中了解更新结果。
* 在 [权限与主机权限](/docs/implementation-guide/permissions-and-host-permissions) 中设计最小权限访问。
* 了解 Extension.js 如何处理 [浏览器特定的 manifest 字段](/docs/features/browser-specific-fields)。
* 在 [页面重载与热模块替换（HMR）](/docs/features/reload-and-hmr) 中了解开发期的更新流程。
