Chrome扩展注入async异步函数报ReferenceError错误该如何解决?
问题原因及解决方案
async函数注入后变量未定义问题
问题根源
项目构建工具(如Webpack/Babel/Vite等)将async/await语法转译为了依赖regeneratorRuntime的ES5兼容代码,转译后的代码引用了构建工具注入的辅助变量,这些变量仅存在于扩展的运行上下文,不会随func参数注入到页面,因此运行时报变量未定义。
解决方案
- 调整构建配置,禁用async/await转译:Chrome扩展仅需兼容Chrome浏览器,直接将构建目标设置为Chrome 90及以上即可:
- Babel配置中移除
@babel/plugin-transform-async-to-generator、@babel/plugin-transform-regenerator等转译插件 - tsconfig.json中将
target字段设置为ES2020或更高 - Vite配置中设置
build.target: 'chrome90'
- Babel配置中移除
- 改用
code参数传递注入代码:不要用func参数传递函数对象,改为直接传递字符串形式的代码,构建工具不会处理字符串内容,不会出现转译依赖丢失问题:
chrome.scripting.executeScript({ target: { tabId: tab.id }, code: ` (async () => { console.log("Does it work?"); // 其他异步逻辑 })(); ` });
Chrome API调用then报错问题
问题根源
Chrome API的Promise支持存在版本和场景限制:
- 仅Manifest V3版本的扩展支持Chrome API的Promise调用,Manifest V2所有API仅支持回调形式
- Chrome 89及以上版本才完成常用API的Promise适配,低于该版本的浏览器调用API不会返回Promise
- 若注入代码时指定了
world: "MAIN"(页面主上下文),该环境下没有Chrome扩展API,调用chrome.storage会直接失败
解决方案
- 优先使用Manifest V3开发,在manifest.json中设置
"minimum_chrome_version": "89",即可直接使用Promise形式的API - 如需兼容更低版本Chrome,改用回调形式调用API:
chrome.storage.local.set({ someArray: [] }, () => { if (chrome.runtime.lastError) { console.error('操作失败', chrome.runtime.lastError); return; } console.log("It worked!"); });
- 如需在页面主上下文操作存储,先在默认的隔离世界(ISOLATED)调用Chrome API,再通过
window.postMessage和主上下文传递数据。
内容的提问来源于stack exchange,提问作者Jpst
相关产品推荐
相关产品推荐

