🚀 省流助手(速通结论):
- 思维脱钩:Node 服务不是 Web 组件。放弃“单文件 Bundle”执念,改走 “业务代码打包 + 生产环境安装依赖” 的工业化路径。
- 物理隔离:将所有 Node 原生依赖标记为
external,利用 Node 原生模块查找机制对抗打包工具的“环境互操作性”误判。 - 路径安全:在 ESM 环境下彻底告别
__dirname,坚持使用import.meta.url动态寻址,确保物理路径的绝对确定性。 - 运维友好:依赖外置不仅是为了避坑,更是为了满足生产环境的 SCA 安全扫描与应急热修复主权。
一、 引言:Web 技术栈的“同名不同命”
在前端开发者的眼中,HTML/CSS/JS 是万能的。我们用它们盖网页,也用它们盖 PWA(离线应用) 和 浏览器插件(Extension) 。
初学者最容易产生的错觉是: “不就是写个 Web App,再配个 manifest.json 吗?” 图破了。 同样叫 manifest.json,它们背后的运行逻辑、权限边界和宿主关系,简直是云泥之别。
二、 核心对比:一份配置,两个世界
为了直观对比,我们直接看两者的代码差异。
- PWA 的
manifest.json:网页的“超级进化名片”
PWA 的核心目标是让网页“看起来”像原生 App。它的配置侧重于 UI 展现 和 离线入口。
json
{
"short_name": "AI工具箱",
"name": "极简 AI 助手 PWA 版",
"icons": [{ "src": "icon-192.png", "sizes": "192x192", "type": "image/png" }],
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#4A90E2",
"description": "基于标准 Web 协议的独立工具"
}
请谨慎使用此类代码。
- 核心权杖:
display: standalone(抹除浏览器地址栏)和Service Worker(拦截网络请求做缓存)。
- 浏览器插件的
manifest.json(V3):浏览器的“特权准入证”
插件的核心目标是“干涉”浏览器的行为。它的配置侧重于 权限声明 和 脚本注入。
json
{
"manifest_version": 3,
"name": "AI 网页助手插件",
"permissions": ["sidePanel", "activeTab", "storage"],
"host_permissions": ["https://api.openai.com*"],
"background": { "service_worker": "background.js" },
"action": { "default_title": "点击唤起 AI" },
"side_panel": { "default_path": "sidepanel.html" },
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["inject.js"]
}]
}
请谨慎使用此类代码。
- 核心权杖:
host_permissions(跨域白名单)和content_scripts(强行入侵他人网页 DOM)。
三、 三大本质区别
- 宿主关系的“寄生”与“独立”
- PWA 是独立的。它运行在浏览器提供的标准沙盒里,虽然可以安装到桌面,但本质上它不具备修改其他网站的能力。
- 浏览器插件 是寄生的。它必须依附于浏览器进程。它可以“偷看”用户正在浏览的银行页面,也可以在 GitHub 页面上强行塞入一个 AI 总结按钮。
- 权限边界的“降维打击”
- PWA 极其卑微:它受严格的 CORS(跨域资源共享) 限制。如果 AI 接口没配置允许跨域,PWA 直接报红。
- 插件 极其嚣张:只要在
host_permissions里声明了,它就可以无视 CORS 访问任何接口。这对 AI 开发者来说是巨大的吸引力。
- 生命周期与 Service Worker
- PWA 的 SW 是为了 “快” :它像一个代理服务器,守在网络请求的门口,决定是走缓存还是走网络。
- 插件的 SW 是为了 “等” :它是事件驱动的后台进程。它平时休眠,只有当用户“点击了右键菜单”或“切换了标签页”时才会被唤醒。
四、 避坑指南:工程化路径的“执念”
正如省流助手所言,无论你开发哪种形态,一旦涉及到复杂的 Node 逻辑(尤其是在 VS Code 插件或 Electron 环境下),不要尝试将所有东西 Bundle 在一起。
- 路径坑:在 PWA 环境下,路径是相对于 URL 的;但在插件(特别是含有 Node 环境的插件)中,
__dirname会因为打包工具的混淆而失效。请始终坚持import.meta.url。 - 安全坑:插件拥有极高权限。在
manifest.json中,遵循 最小权限原则。如果你只需要 AI 侧边栏,就不要申请history权限,否则在 Chrome Web Store 上架时会面临地狱级别的审核。
五、 结语
- 如果你想做一个独立工具,追求全平台覆盖:选 PWA。
- 如果你想改变上网体验,甚至想做“网页版 Copilot”:选浏览器插件。
manifest.json 只是外皮,理解背后浏览器引擎对权限的让渡逻辑,才是高级前端的进阶之路。