Chrome扩展使用Rollup打包出现exports未定义错误如何解决
报错是因为打包产物中残留了CommonJS规范的exports语法,Chrome扩展的运行上下文(包括background的页面/Service Worker)属于浏览器环境,没有内置CommonJS模块系统,无法识别exports、require等全局变量,因此抛出引用错误。
根本原因是当前使用的Rollup基础配置没有处理第三方依赖(此处为socket.io-client)中的CommonJS格式代码,未将CommonJS语法转为浏览器可识别的格式。
第一步:安装Rollup CommonJS兼容插件
安装@rollup/plugin-node-resolve(用于解析node_modules中的第三方依赖)和@rollup/plugin-commonjs(用于将CommonJS代码转为ES模块代码):npm install @rollup/plugin-commonjs @rollup/plugin-node-resolve --save-dev第二步:修改rollup.config.js配置
调整配置引入上述插件,同时指定输出格式为浏览器兼容的IIFE(立即执行函数)格式,避免模块语法残留:import merge from 'deepmerge'; import { createBasicConfig } from '@open-wc/building-rollup'; // 新增引入插件 import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; const baseConfig = createBasicConfig(); export default merge(baseConfig, { input: './out-tsc/src/background/background.js', output: { dir: 'dist', // 新增:指定输出格式为IIFE,适配浏览器环境 format: 'iife', // 可选:如果不需要暴露导出内容到全局,设置exports为none避免警告 exports: 'none' }, // 新增:添加兼容插件 plugins: [ resolve(), commonjs() ] });第三步:调整tsconfig.json配置
将esModuleInterop设置为true,优化CommonJS模块的导入兼容性,避免导入socket.io-client时出现语法问题:{ "compilerOptions": { "target": "es2018", "module": "esnext", "moduleResolution": "node", "noEmitOnError": true, "lib": ["es2017", "dom"], "strict": true, // 修改此处为true "esModuleInterop": true, "outDir": "out-tsc", "rootDir": "./" }, "include": [ "./src/background/background.ts", "./src/background/**/*.ts" ] }第四步:重新执行打包命令
运行原编译命令即可生成正常运行的产物:tsc --build ./tsconfig-background.json && rollup -c rollup.config.js
如果你使用的是Manifest V3版本的Chrome扩展,且background使用Service Worker,也可以选择将输出格式设置为es(ES模块),此时需要在manifest.json的background配置中添加"type": "module"声明,同样可以解决该问题。
内容的提问来源于stack exchange,提问作者Jeanluca Scaljeri

