Chrome扩展报错Uncaught SyntaxError: Unexpected token 'export'
报错核心原因
- Chrome扩展默认注入的
content.js运行在独立的隔离世界(Isolated World),且默认被解析为普通脚本而非ES模块,直接写export语法会被普通JS解析器识别为非法标记,直接抛出语法错误。 - Popup弹窗的运行上下文和content script上下文完全隔离,二者不共享JS作用域,无法通过原生ES模块的
import/export直接跨上下文传递变量。 - 在popup的HTML文件中用
<script type="module">引入content.js,加载的是运行在popup上下文的独立JS副本,和注入到网页中的content script实例没有任何关联,既不能解决语法报错,也拿不到网页环境下content.js里生成的变量。
修复方案
根据实际使用场景二选一即可:
场景1:需要获取网页环境下content.js生成的运行时变量
这种场景不要用import/export,改用Chrome扩展官方的消息通信机制传值:
- 移除
content.js里的export语句,新增消息监听逻辑,对外暴露需要传递的变量:// content.js 原有逻辑保留 const userubi = userubi; // 原有定义的变量 // 新增消息监听 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === 'GET_USERUBI') { sendResponse({ value: userubi }); } return true; // 保持消息通道开放,避免响应被截断 }); - 移除
popup-sign-in-script.js里的import语句,改为向当前标签页的content script发消息取值:// popup-sign-in-script.js 原有逻辑保留 async function loadUserubi() { // 获取当前激活的标签页 const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true }); // 向标签页内的content script发请求 const res = await chrome.tabs.sendMessage(activeTab.id, { type: 'GET_USERUBI' }); return res.value; } // 调用示例 loadUserubi().then(userubi => { // 此处拿到目标值,写后续业务逻辑 console.log(userubi); }); - 清理
popup-sign-in.html里多余的引入,删除加载content.js的script标签,只保留popup自身脚本的引入即可。 - 检查
manifest.json(Manifest V3版本)配置,确保权限和注入规则正确:{ "permissions": ["activeTab", "tabs"], "content_scripts": [ { "matches": ["<all_urls>"], // 替换为实际需要注入的站点规则 "js": ["content.js"] } ] }
场景2:需要抽离公共逻辑给popup和content script复用
这种场景不要直接复用注入用的content.js,单独抽离公共模块文件:
- 新建独立的公共模块文件比如
common.js,存放两边都要用的变量和逻辑:// common.js export const userubi = '公共变量值'; - 如果
content.js需要引用这个公共模块,在manifest.json里把content script的类型声明为module,支持ES模块语法:{ "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "type": "module" // 声明为模块后,content.js里才可以正常使用import/export语法 } ] } popup-sign-in-script.js里直接从公共模块导入值即可,不要从注入用的content.js导入:import { userubi } from './common.js'; // 后续业务逻辑
内容的提问来源于stack exchange,提问作者TheGuyFromThePlace
相关产品推荐
相关产品推荐

