You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firefox扩展出现‘import声明仅能在模块顶层’错误求助

解决Firefox扩展Content Script中ES模块导入报错问题

问题场景

项目目录结构:

app
  js
    foo.js
  content.js
  manifest.json
  background.js

各文件代码

foo.js:

function myFunc() {
  let hello = 'hello from foo.js';

  return hello;
}

export {myFunc};

content.js:

import { myFunc } from './js/foo.js';

browser.runtime.onMessage.addListener((message) => {
  let result = myFunc();
  console.log(result);
});

manifest.json(原配置):

{
  "manifest_version": 2,
  "name": "test",
  "version": "1.0.0",
  "description": "A notetaking tool for YouTube videos",
  "icons": {
    "48": "icons/border-48.png"
  },
  "background": {
    "scripts": ["background.js"]
  },
  "permissions": [
    "tabs"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "run_at": "document_start"
    }
  ],
  "web_accessible_resources":[
    "icons/my_icon.svg",
    "js/*"
  ]
}

background.js:

browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
   browser.tabs.sendMessage(tabId, {message: 'hello from background.js'});
});

报错信息

import declarations may only appear at the top level of a module

错误原因

Manifest V2 中的 Content Script 默认以普通脚本而非ES模块的方式加载,即使import语句在文件顶部,浏览器也无法识别模块语法,因此抛出错误。

解决方案

方案1:升级到 Manifest V3(推荐)

Manifest V3 原生支持将 Content Script 作为模块加载,修改步骤如下:

  1. 更新manifest.json:
    • 将manifest_version改为3
    • 在content_scripts配置中添加"type": "module"
    • 调整background配置为service_worker(V3强制要求)

修改后的manifest.json:

{
  "manifest_version": 3,
  "name": "test",
  "version": "1.0.0",
  "description": "A notetaking tool for YouTube videos",
  "icons": {
    "48": "icons/border-48.png"
  },
  "background": {
    "service_worker": "background.js"
  },
  "permissions": [
    "tabs"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "run_at": "document_start",
      "type": "module"
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["icons/my_icon.svg", "js/*"],
      "matches": ["<all_urls>"]
    }
  ]
}
  1. 保持content.js和foo.js代码不变,此时浏览器会将content.js作为模块加载,import语法可正常工作。

方案2:Manifest V2 下动态注入模块脚本

如果暂时无法升级到V3,可通过Background Script动态注入模块形式的Content Script:

  1. 修改manifest.json:
    • 移除原有的content_scripts配置
    • 在web_accessible_resources中添加content.js

修改后的manifest.json片段:

{
  "manifest_version": 2,
  // 其他原有配置保持不变
  "web_accessible_resources":[
    "icons/my_icon.svg",
    "js/*",
    "content.js"
  ]
}
  1. 更新background.js,使用executeScript注入模块脚本:
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  // 确保页面加载完成后执行注入
  if (changeInfo.status === 'complete') {
    browser.tabs.executeScript(tabId, {
      file: 'content.js',
      runAt: 'document_start',
      type: 'module'
    }).catch(err => console.error('注入脚本失败:', err));
  }
});
  1. 保持content.js和foo.js代码不变,注入后的脚本会以模块形式执行,import语法生效。

注意:该方案要求Firefox版本在89及以上,因为Manifest V2下的executeScript支持type: 'module'是从该版本开始的。

内容的提问来源于stack exchange,提问作者Diehardwalnut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:23:14