manifest.json 详解:MV3 字段速查
💡 一句话总结:manifest.json 是插件唯一缺不得的文件——3 个平台必填字段打底,2 个商店必填字段上架,其余按功能往上加。
上一课 C2 第一个 Chrome 插件里,manifest.json 是逐字抄的:能跑,但每个字段为什么这么写,未必说得清。这一课把它逐个拆开——哪些字段缺了 Chrome 直接拒载、哪些只在上架时才查、高频可选字段怎么写。以后不管自己写还是让 AI 生成,你都能看懂、能改、能排错。
学完你能做什么
- 说出 manifest.json 的 3 个平台必填字段和 2 个商店必填字段,以及各自的长度、格式限制
- 从最小示例开始,把 action、background、content_scripts、permissions 一个个加进自己的 manifest
- 用一张 MV3 字段速查表查到全部 46 个字段的作用
- 避开新手三大翻车点:JSON 写注释、照抄 MV2 老教程、版本号不合规
- 上架前按清单核对一遍,知道哪些信息上传后改不了
你现在的困境
- 「AI 帮我生成了 manifest.json,但哪个字段是必须的、哪个字段是干嘛的,我完全看不懂」
- 「照网上老教程抄,字段总是对不上——后来才知道那是 MV2 的写法,白忙一场」
- 「本地加载明明好好的,一上传商店就报 Cannot parse the manifest,查半天不知道错在哪」
什么时候用这一招
当你需要:
- 查某个 manifest 字段的写法和限制(name 最长多少、version 能写几段)
- 从零拼一份能加载的 manifest.json,或给现有插件加新功能的字段
- 上架前核对必填项,把「上传后才发现写错」扼杀在上传前
而且不想:
- 通读官方文档里 46 个字段的完整说明——速查表在下面一屏
- 因为字段写错被 Chrome 拒载、被商店拒收
- 分不清 MV2 和 MV3 写法,抄错教程还以为是 Chrome 坏了
🎒 开始前的准备
- 走完 C2 第一个 Chrome 插件,手上有那份能跑的 Hello World manifest.json
- 一个能编辑 JSON 文件的工具(记事本就行,VS Code 这类编辑器更舒服)
chrome://extensions扩展管理页开着,方便随时刷新验证- 10 分钟
核心思路
Chrome 对每个插件只有一条硬性要求:根目录必须有一份 manifest.json,它列出这个插件的结构和行为信息——Chrome 靠它认识插件,商店靠它审核插件。
官方把全部 46 个字段分成四组,新手先记住前两组:
| 分组 | 字段 | 缺了会怎样 |
|---|---|---|
| 平台必填(3 个) | manifest_version、name、version | Chrome 直接拒载,弹错误对话框 |
| 商店上架必填(2 个) | description、icons | 本地能跑,上架过不去 |
| 可选(37 个) | action、background、content_scripts、permissions 等 | 不缺,按功能往上加 |
| 可选·ChromeOS 专用(4 个) | file_handlers 等 | 桌面 Chrome 插件基本用不到 |
两条贯穿全页的铁律,先记下:
- JSON 里不能写注释——上传商店会报
Cannot parse the manifest - manifest.json 必须在根目录——本地加载时选插件文件夹,上架打包 zip 时 manifest 也必须在压缩包根目录,不能套一层文件夹
跟我做
接下来把一份 manifest.json 从 3 个字段一路加到 10 个。就在上一课的 Hello World 文件夹里改,每改一步回 chrome://extensions 点插件卡片上的刷新图标——改 manifest 必须刷新插件才生效。
第 1 步:写下平台必填三项——manifest.json 的地基
为什么:Chrome 加载插件的第一件事就是读 manifest.json,这三个字段缺任何一个,加载直接失败。
新建(或打开)插件根目录的 manifest.json,写入:
{
"manifest_version": 3,
"name": "My First Extension",
"version": "1.0.0"
}三项各自的限制:
| 字段 | 限制 | 说明 |
|---|---|---|
manifest_version | 只支持 3 | MV3 是现在唯一的写法,老教程里的 2 别抄 |
name | 最长 75 字符 | 展示在商店、安装对话框和 chrome://extensions 页 |
version | 1-4 段点分整数,每段 0-65536 | 如 1.0.0,格式错了 Chrome 会明确报错 |
你应该看到:一份只有三个键的 JSON——平台要求的全部就这么多。
想亲眼看格式规则把关,把 version 故意改成 "1.0.0.0.0"(五段)再刷新插件,Chrome 会弹错误对话框:Required value version is missing or invalid. It must be between 1-4 dot-separated integers each between 0 and 65536.——改回 1.0.0 即恢复。
- 小检查:manifest.json 在根目录,三个字段都在,JSON 里没有注释
第 2 步:补上 description 与 icons——凑齐官方最小示例
为什么:这两项不影响本地运行,但上架 Chrome 应用商店必查;官方文档的「最小 manifest 示例」也包含它们。
在刚才的 JSON 里补上这两项,就是官方文档 Minimal Manifest 的原文(name 换成你自己插件的名字也行):
{
"manifest_version": 3,
"name": "Minimal Manifest",
"version": "1.0.0",
"description": "A basic example extension with only required keys",
"icons": {
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
}description:最长 132 字符,展示在商店和扩展管理页icons:一个或多个图标,键是尺寸、值是图片路径
你应该看到:到这里就是官方 Minimal Manifest 的原样。icons 指向的图片要真实存在——上一课 Hello World 用过的图标文件就能拿来用,把 icons 里的路径改成它的实际位置即可。
- 小检查:description 不超过 132 字符;icons 的每个路径都能在文件夹里找到对应文件
第 3 步:加 action 与 background——弹窗和事件中枢
为什么:action 决定工具栏图标点下去发生什么;background 指定插件的 service worker(事件处理器)。上一课的弹窗就是 action 干的活。
把这两个键加进 manifest(注意前一个键末尾补逗号):
"action": {
"default_popup": "hello.html",
"default_icon": "hello_extensions.png"
},
"background": {
"service_worker": "service-worker.js"
}action:定义工具栏图标的外观与行为;default_popup指定点图标弹出的页面,default_icon指定图标图片background:service_worker指向的 JS 文件是插件的「大脑」,按需启动、空闲即停——深入玩法下一课讲
你应该看到:刷新插件后,点工具栏图标,弹窗照常打开。记得先把 service-worker.js 文件建好(内容暂时一行 console.log("background ready") 就行)——manifest 里声明的文件路径都要真实存在。
第 4 步:加 content_scripts 配置——脚本自动跑在指定网页
为什么:想让插件「一打开某类网页就自动改页面」,靠的就是 content_scripts 静态声明——不用点任何按钮,脚本自己注入。
把这段加进 manifest:
"content_scripts": [
{
"matches": ["https://*.nytimes.com/*"],
"css": ["my-styles.css"],
"js": ["content-script.js"]
}
]matches:必填。决定脚本注入哪些页面,用 match pattern 语法书写(如https://*.nytimes.com/*);所有自动运行的 content script 都必须指定 match patternjs/css:可选。按数组顺序注入的 JS / CSS 文件,路径相对插件根目录
你应该看到:刷新插件后打开一个匹配 matches 的页面,脚本自动生效。改 content script 文件后,除了刷新插件还要刷新宿主页面。至于「为什么我的脚本和网页变量互相看不见」——下一课 C4 讲隔离世界。
第 5 步:加 permissions 与 host_permissions 声明
为什么:permissions 启用具体的扩展 API,不声明就调用不了;host_permissions 声明插件可以交互哪些网站——这些网站的权限在安装时就向用户请求。
把这两行加进 manifest:
"permissions": ["storage"],
"host_permissions": ["https://*.example.com/"]permissions:数组里放要启用的 API 名,如storage、scripting、activeTab;只声明真正用到的host_permissions:用 match pattern 列出可交互的网页
你应该看到:刷新插件,加载正常。权限名拼错不会拒载,但扩展页会出现红色的 Errors 按钮——比如把 activeTab 写成 activetab,会提示 Permission 'activetab' is unknown or URL pattern is malformed.。排错的完整套路在 C5。
第 6 步:本地加载验证,上架前逐项核对
为什么:字段写得对不对,只有 Chrome 和商店说了算。本地先过一遍,上架前再核对一遍,省掉最贵的返工。
操作:
- 回
chrome://extensions,点插件卡片上的刷新图标(三步加载法上一课讲过) - 加载失败会弹错误对话框——对照报错改 manifest,改完再刷新
- 准备上架时,逐项核对:
| 核对项 | 标准 |
|---|---|
name / description | ≤75 / ≤132 字符,无错字——上传后改不了 manifest 元数据,发现错字只能改文件、提高版本号、重新打包 |
version | 比已上传的版本大;初版建议设低值如 0.0.0.1,给以后留递增空间 |
| 注释 | JSON 里没有任何注释,否则上传报 Cannot parse the manifest |
| 打包 | zip 压缩包根目录直接是 manifest.json,不能套文件夹 |
你应该看到:本地加载无错误对话框、无红色 Errors;上架的 zip 解开第一层就能看到 manifest.json。注册、提审、审核的完整流程在 C6。
📋 MV3 字段速查表
💡 怎么用这张表
先问两个问题:这个字段属于哪一层(平台必填 / 商店必填 / 可选)?我要的功能归哪一组(界面 / 权限 / 网络 / 分发)?定位到行,照着写、核对限制,再回页面对应步骤看展开说明。本表字段与限制整理自 Chrome 官方 Manifest reference 文档。
平台必填(3 个)
| 字段 | 限制 | 作用 |
|---|---|---|
manifest_version | 整数,唯一支持值 3 | manifest 格式版本 |
name | ≤75 字符 | 商店、安装对话框、chrome://extensions 显示的名称 |
version | 1-4 段点分整数,每段 0-65536 | 版本号,上传新版本必须比上一个大 |
商店上架必填(2 个)
| 字段 | 限制 | 作用 |
|---|---|---|
description | ≤132 字符 | 商店与扩展管理页的描述 |
icons | 一张或多张图标 | 代表插件的图标 |
高频可选(先认识这 5 个)
| 字段 | 写法要点 | 作用 |
|---|---|---|
action | default_popup 指向弹窗页,default_icon 指定图标 | 工具栏图标的外观与行为 |
background | {"service_worker": "service-worker.js"} | 指定作为事件处理器的 service worker |
content_scripts | matches 必填 + js / css 数组 | 打开匹配网页时自动注入的 JS/CSS |
permissions | API 名数组,如 ["storage"] | 启用特定扩展 API |
host_permissions | match pattern 数组 | 声明可交互网页,安装时请求授权 |
其他可选字段(按用途分组)
界面与交互
| 字段 | 作用 |
|---|---|
commands | 定义插件内的键盘快捷键 |
options_page | 指定 options.html 作为插件的设置页 |
options_ui | 让用户在扩展管理页内修改插件选项 |
side_panel | 指定显示在侧边栏的 HTML 页面 |
omnibox | 在 Chrome 地址栏注册关键词 |
chrome_url_overrides | 覆盖 Chrome 默认页面 |
devtools_page | 定义使用 DevTools API 的页面 |
权限与安全
| 字段 | 作用 |
|---|---|
optional_permissions | 声明可选的 API 权限 |
optional_host_permissions | 声明可选的 host 权限 |
content_security_policy | 限制插件可加载的脚本、样式等资源 |
externally_connectable | 指定哪些网页和插件可以连接到你的插件 |
web_accessible_resources | 定义可被网页或其他插件访问的插件内文件 |
sandbox | 定义无法直接使用扩展 API 的沙箱页面 |
incognito | 无痕模式下的行为,取值 spanning / split / not_allowed |
key | 为开发用途指定插件 ID |
网络与数据
| 字段 | 作用 |
|---|---|
declarative_net_request | 声明式网络请求的静态规则,可拦截和修改网络请求 |
oauth2 | 配置 OAuth 2.0(client_id 与 scopes) |
storage | 为托管存储区声明 JSON schema |
tts_engine | 把插件注册为文字转语音引擎 |
mime_types_handler | 把插件注册为某 MIME 类型(如 application/pdf)的处理器 |
requirements | 列出使用插件所需的技术 |
版本与分发
| 字段 | 作用 |
|---|---|
version_name | 给人看的版本别名(如 "1.0 beta");不写则显示 version |
minimum_chrome_version | 可安装插件的最低 Chrome 版本;更低版本显示不兼容、无法安装也不自动更新 |
homepage_url | 插件主页 URL;不写默认为商店页 |
update_url | 自托管分发(不上架商店)时的更新页地址 |
import | 允许向插件导入资源 |
export | 允许从插件导出资源 |
国际化与展示
| 字段 | 作用 |
|---|---|
default_locale | 多语言插件的默认语言(如 en);本地化插件必填,非本地化插件不能用 |
short_name | 短名称,≤12 字符;不写则截断 name 展示 |
Chrome 设置
| 字段 | 作用 |
|---|---|
chrome_settings_overrides | 覆盖部分 Chrome 设置 |
cross_origin_embedder_policy | 配置 Cross-Origin-Embedder-Policy 请求头 |
cross_origin_opener_policy | 配置 Cross-Origin-Opener-Policy 请求头 |
ChromeOS 专用(4 个)
| 字段 | 作用 |
|---|---|
file_browser_handlers | 访问 ChromeOS 文件浏览器相关 API |
file_handlers | 指定 ChromeOS 插件处理的文件类型 |
file_system_provider_capabilities | 让插件创建 ChromeOS 可用的文件系统 |
input_components | 使用输入法编辑器(IME)API |
检查点 ✅
- manifest.json 在插件根目录,JSON 里没有任何注释
manifest_version是 3;name≤75 字符;version是 1-4 段点分整数- 要上架的话:
description≤132 字符,icons每个路径都真实存在 content_scripts的matches已写,且符合 match pattern 语法permissions只声明真正用到的 API,没有拼写错误
踩坑提醒
❌ 在 manifest.json 里写注释
{
"manifest_version": 3, // MV3 写死
"name": "My Extension"
}原因:JSON 不支持注释,商店上传时直接报 Cannot parse the manifest。 正确做法:删掉全部注释再上传;想留说明,写到 README 或旁边的文档里。
❌ 照抄老教程,manifest_version 写成 2
原因:网上大量教程还是 MV2 时代的写法,而 MV3 里 manifest_version 唯一支持的值是 3,照抄老写法会白干。 正确做法:新插件一律 "manifest_version": 3;拿不准的字段回本页速查表对一遍。
❌ version 随手写,上传新版本被拒
"version": "1.0.0.0.0" // ❌ 五段,超了
"version": "0.0.0.1" // ✅ 初版设低值,以后只往上加原因:version 必须是 1-4 段点分整数、每段 0-65536;而且商店要求每个新上传的版本号必须比上一个大。 正确做法:初版设 0.0.0.1 这类低值,每次发布只递增,永远有空间。
❌ 上传后才发现 name 里有个错字
原因:上传商店后,manifest 元数据在开发者后台改不了——不是权限问题,是规则如此。 正确做法:上传前逐字核对 name 和 description;真错了就只能改 manifest、提高 version、重新打包上传。
🔧 进阶技巧(可选)
- 给编辑器挂官方 manifest schema:在代码编辑器里关联 manifest schema(json.schemastore.org/chrome-manifest),字段写错、必填项缺失当场标红,不用等 Chrome 拒载才发现
version_name与version分工:version是给 Chrome 比大小的机器版本号;version_name(如"1.0 beta")是给人看的别名,展示在扩展管理页。想要「好看的版本名 + 严格递增的版本号」,两个都写short_name救场:名字太长、展示空间不够时,short_name(≤12 字符)顶上;不写则 Chrome 截断name显示
本课小结
✅ 这节课你搞定了:
- manifest.json 的分层结构:平台必填 3 项、商店必填 2 项、可选 41 项(含 ChromeOS 专用 4 项)
- 从最小示例逐步加出 action、background、content_scripts、permissions 的完整写法
- version 的格式规则与「只递增」纪律,加上 JSON 无注释、根目录两条铁律
- 上架前核对清单:元数据上传后改不了,改错字 = 发新版本
关键配置字段回顾:
| 字段 | 推荐值 / 限制 | 说明 |
|---|---|---|
manifest_version | 3 | 唯一支持的值 |
name | ≤75 字符 | 三处展示的插件名 |
version | 0.0.0.1 起步,只递增 | 1-4 段点分整数,每段 0-65536 |
description | ≤132 字符 | 商店必填 |
icons | 48 / 128 两档起步 | 商店必填,路径要存在 |
action.default_popup | hello.html | 点图标的弹窗页 |
background.service_worker | service-worker.js | 事件中枢脚本 |
content_scripts[].matches | match pattern,必填 | 决定注入哪些页面 |
permissions | 只列用到的 API | 如 ["storage"] |
host_permissions | match pattern 数组 | 安装时请求授权 |
下一课预告
字段声明好了,下一课 C4 Content Script 与 Service Worker:插件的大脑和手脚把 manifest 里这两个字段背后的机制讲透。
你会学到:
- content script 与 service worker 的官方定义,各自能干什么
- 「隔离世界」:为什么你的脚本和网页变量互相看不见
- 静态声明、动态声明、编程式注入三种方式怎么选
- service worker 按需启动、空闲即停的脾气,以及什么时候用谁