如何在Vite+React的Chrome扩展Service Worker中导入模块?
解决Chrome扩展Vite项目中后台脚本导入Supabase-js的问题
问题场景
在基于Vite+React开发Manifest V3版本的Chrome扩展时,目标是让扩展与Web应用共享Supabase认证会话,但后台服务脚本background.js导入@supabase/supabase-js时出现构建错误,注释导入语句后npm run build可正常执行。尝试过crxjs/vite-plugin(不兼容Vite4)、importScripts方法及调整Vite配置均未解决。
解决方案步骤
1. 调整文件结构与Vite配置
将原public/background.js移动到src/background.js,让Vite将其纳入打包流程,而非当作静态资源处理。同时修改vite.config.js的Rollup配置,确保后台脚本正确输出:
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], build: { outDir: 'dist', rollupOptions: { input: { index: './index.html', background: './src/background.js', // 指向src目录下的后台脚本 }, output: { // 确保后台脚本输出到dist根目录,与manifest配置匹配 entryFileNames: '[name].js', chunkFileNames: 'assets/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash].[ext]', }, }, }, envDir: '.', // 指定环境变量目录 });
2. 修正background.js的导入路径
不要直接导入node_modules内的文件,改用包名导入,让Vite自动处理依赖预构建:
import { createClient } from '@supabase/supabase-js'; const options = { auth: { autoRefreshToken: true, persistSession: true, detectSessionInUrl: false, // 后台脚本无需检测URL中的会话 storage: { async getItem(key) { const storage = await chrome.storage.local.get(key); return storage?.[key]; }, async setItem(key, value) { await chrome.storage.local.set({ [key]: typeof value === 'string' ? JSON.parse(value) : value, }); }, async removeItem(key) { await chrome.storage.local.remove(key); }, }, }, }; export const supabase = createClient( import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_ANON_KEY, options );
3. 确认Manifest配置
确保manifest.json中后台脚本的type为module(已配置),且构建后dist目录下的background.js路径与配置一致:
"background": { "service_worker": "background.js", "type": "module" }
关键说明
- 直接导入
node_modules路径会导致Rollup打包逻辑异常,使用包名导入可触发Vite的依赖预构建,正确处理Supabase库的模块化转换。 - 将后台脚本移至
src目录,让Vite完整参与其打包流程,避免静态资源的无处理输出。 - 调整Rollup的
output配置,确保后台脚本输出到dist根目录,与Manifest中指定的路径匹配。
内容的提问来源于stack exchange,提问作者cpppatrick
相关产品推荐
相关产品推荐

