Chrome 扩展开发与 Chrome Web Store 上架全流程实战避坑

前言

各位友人们好啊。在把本地写好的 Chrome 扩展提交到 Chrome Web Store 商店时,Google 对资质、权限声明和隐私政策的要求非常细致,稍有含糊就容易被打回。

这里把从注册账号、打包构建到过审表单填写的完整流程和踩坑点整理记录一下,方便后续查阅。


1. 账号注册与资质声明

1.1 注册费用

访问 Chrome 开发者控制台,需要支付 5 美元 的一次性注册费(需使用 Visa/MasterCard 等外币信用卡)。

1.2 EEA 交易者身份选择

注册时会提示根据欧洲经济区(EEA)法律进行身份声明:

  • 交易者 (Trader):适用于涉及商业销售、付费订阅或公司名义发布的产品。会强制公开你的联系地址和电话
  • 非交易者 (Non-trader):个人开发、免费开源、无商业交易的项目直接选此项。

普通开源/免费工具建议直接选 「非交易者」,避免泄露个人隐私信息。后续如有商业化需求可在后台变更。

1.3 新账号发布配额

后台若显示“您已发布 0 个扩展程序(限额为 2 个)”,这是 Google 对新注册账号的常规风控机制。正常发布并通过审核后,配额会自动扩容。


2. 构建打包与多语言

2.1 多语言配置(i18n)

Chrome 商店会直接读取插件内的语言配置。若要支持双语,需遵循标准规范:

1
2
3
4
5
6
dist/
├── _locales/
│ ├── en/messages.json
│ └── zh_CN/messages.json
├── manifest.json
└── ...

manifest.json 中引用:

1
2
3
4
5
{
"name": "__MSG_appName__",
"description": "__MSG_appDesc__",
"default_locale": "zh_CN"
}

2.2 打包脚本

切勿直接打包项目根目录。需编写脚本仅归档构建产物(dist 目录),剔除源码与调试文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os, zipfile

def build_package():
dist_dir = 'dist'
output_zip = 'extension-release.zip'

with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
for root, _, files in os.walk(dist_dir):
for file in files:
if file.startswith('.') or file.endswith('.map'):
continue
full_path = os.path.join(root, file)
arcname = os.path.relpath(full_path, dist_dir)
zf.write(full_path, arcname)
print(f"Package created: {output_zip}")

if __name__ == '__main__':
build_package()

3. 隐私权规范填写(审核重点)

这一步在控制台的 “隐私权规范 (Privacy practices)” 标签页下,也是人工审核的核心。

3.1 单一用途说明 (Single Purpose)

必须用精炼的语言概括核心功能,避免宽泛词汇:

中文:本扩展程序的单一用途是:基于艾宾浩斯遗忘曲线与 SM-2 间隔重复算法,帮助用户在 LeetCode 刷题过程中建立科学的复习计划与记忆追踪,并在题目页面提供轻量打卡与提醒功能。
英文:The single purpose of this extension is to help developers track and review LeetCode coding problems using the Ebbinghaus spaced repetition curve and SM-2 memory algorithm, providing inline review status and progress tracking directly on LeetCode pages.

3.2 权限理由申明

所有在 manifest.json 中声明的权限均需填写理由:

权限项申明理由
storage用于在本地(chrome.storage.local)存储复习进度、算法参数与做题笔记,数据不上传外部服务器。
alarms用于后台定时计算每日待复习题目,并更新插件图标角标数字,无需常驻后台进程。
activeTab用于在用户打开弹窗时,临时获取当前标签页的 URL 与标题,支持一键收录当前题目。
tabs用于在点击待复习卡片时在新标签页中打开对应题目链接。
主机权限 (*://leetcode.cn/* 等)仅在指定域名页面注入脚本展示复习状态胶囊,并在提交成功时记录打卡。不访问其他网站。

3.3 远程代码

  • 选择:「不,我并未使用远程代码」
  • Manifest V3 规定所有可执行脚本必须打包在本地扩展包内,禁止外部 CDN 加载或 eval()

3.4 数据使用与合规

  • 收集哪些用户数据:如果插件纯本地运行、无服务器回传,所有数据类型均不要勾选,全部留空
  • 合规声明:勾选底部的 3 个确认复选框(不向第三方出售数据、不用作非单一用途、不用作信贷评估)。

3.5 隐私权政策网址 (Privacy Policy URL)

申请了主机权限或敏感权限时该项为必填。可直接在 GitHub 项目中新建 PRIVACY.md,使用公开文件链接填入:

1
https://github.com/<用户名>/<仓库名>/blob/master/PRIVACY.md

隐私政策只需简明说明:不收集个人信息、数据纯本地存储、列出权限用途并附上联系方式即可。


4. 提交审核

确认各项填写无红色提示后,点击右上角 「提交以供审核」

  • 审核周期通常为 1 ~ 3 个工作日
  • 涉及主机权限的扩展可能触发深度审核(In-depth review),耗时会稍有延长。审核通过后会有邮件提醒并自动上架。

在最后附上这次写的浏览器插件,用来刷题的。供大家体验 leetcode刷题插件