eval,不允许 new Function,也不允许动态编译的代码。当某个功能确实需要这些能力时(模板引擎、代码 playground、运行 AI 生成的片段),Manifest V3 提供了 sandbox 页面:用放弃 chrome.* API 访问权限换取一份更宽松 CSP 的扩展页面。
声明页面
manifest.json
sandbox.html:直接引用你的 .ts/.tsx 即可构建。入口写法参见 HTML 指南。
sandbox 页面能做什么、不能做什么
sandbox 页面运行在一个独立 origin 中,因此它无法读取扩展的 storage、调用扩展 API,也无法触及其他页面的 DOM。所有交互都通过消息传递完成。
嵌入与通信
在一个普通扩展页面中用 iframe 加载 sandbox,然后通过postMessage 通信:
newtab.html
newtab.ts
sandbox.ts
chrome.* 访问权限,并扮演中间人的角色:它读取 storage、调用 API,并把纯数据传入和传出 sandbox。
别搞混了:background.type
一个常见的混淆:"background": {"type": "module"} 和 sandbox 化毫无关系。它声明 background service worker 是一个 ES 模块,这样 import 语句在注册时就能正常工作。当你的 background 入口使用 ESM 语法时,Extension.js 会自动设置它,因此你几乎不需要手写。如果你的疑惑是 service worker 里的 import 失败,请看 Background 脚本;如果是关于运行动态代码,那你就来对地方了。
自定义 sandbox CSP
你可以通过 manifest 中的content_security_policy.sandbox 进一步放宽或收紧 sandbox 的 CSP。请把 script-src 收得尽可能窄——只满足该功能所需即可;sandbox 的目的是把动态代码关起来,而不是为了绕过安全审查。安全清单 列出了审核者会关注的点。

