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

Vite+Chrome Extension Manifest v3:页内脚本import语句模块报错

问题描述

基于chrome-extension-boilerplate-react-vite项目创建扩展,在manifest中将background设置为模块:

background: {
  service_worker: "background.js",
  type: "module",
},

在后台服务中通过以下方式动态注册内容脚本:

await chrome.scripting.registerContentScripts([
  {
    id: currInpageId,
    matches: ["file://*/*", "http://*/*", "https://*/*"],
    js: [`inpage-${inpageType}.js`],
    runAt: "document_start",
    allFrames: true,
    world: "MAIN",
  },
]);

同时在vite.config中把inpage文件配置为单独输入项:

input: {
  ...inpageTypes.reduce(
    (acc, inpageType) => ({
      ...acc,
      [`inpage-${inpageType}`]: resolve(
        inpageDir,
        `inpage-${inpageType}.ts`
      ),
    }),
    {}
  ),
},

运行扩展时出现错误:

Uncaught SyntaxError: Cannot use import statement outside a module

解决方法

错误根源是注入到MAIN world的inpage脚本被打包为ES模块,但MAIN world默认不允许在非模块脚本中使用import语句,以下两种方案可解决:

方案一:将inpage脚本打包为自执行格式(IIFE)

修改vite构建配置,给inpage相关入口单独指定输出格式为IIFE,打包后的代码会合并所有依赖为自执行函数,消除import语句:

// vite.config.js
import { resolve } from 'path';

export default {
  // 其他原有配置...
  build: {
    rollupOptions: {
      input: {
        // 保留background、popup等其他入口
        ...inpageTypes.reduce(
          (acc, inpageType) => ({
            ...acc,
            [`inpage-${inpageType}`]: resolve(inpageDir, `inpage-${inpageType}.ts`),
          }),
          {}
        ),
      },
      output: {
        entryFileNames: (chunkInfo) => {
          if (chunkInfo.name.startsWith('inpage-')) {
            return '[name].js'; // 保持inpage文件名简洁
          }
          return 'assets/[name]-[hash].js'; // 其他文件默认命名规则
        },
        format: (chunkInfo) => {
          // 给inpage脚本指定IIFE格式
          if (chunkInfo.name.startsWith('inpage-')) {
            return 'iife';
          }
          return 'es'; // 其他文件保留ES模块格式
        },
      },
    },
  },
};

方案二:将inpage脚本注册为模块类型

若希望保留ES模块写法,需在注册内容脚本时添加type: "module"参数,同时确保vite打包的inpage脚本为ES模块格式:

await chrome.scripting.registerContentScripts([
  {
    id: currInpageId,
    matches: ["file://*/*", "http://*/*", "https://*/*"],
    js: [`inpage-${inpageType}.js`],
    runAt: "document_start",
    allFrames: true,
    world: "MAIN",
    type: "module", // 新增该参数
  },
]);

注意:此方案要求目标浏览器支持ES模块,且inpage脚本的依赖需正确打包为ES模块,避免运行时解析错误。

推荐优先使用方案一,IIFE格式兼容性更强,不会受限于浏览器模块支持,也能规避MAIN world中模块带来的隔离问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:43:15