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

React TypeScript项目中Vite PWA Service Worker注册失败求助

解决vite-pwa-plugin在dev环境下Service Worker的import语法错误

问题现象

使用vite-pwa-plugin的injectManifest策略自定义Service Worker时,浏览器持续抛出以下错误:

Uncaught SyntaxError: Cannot use import statement outside a module (at dev-sw.js?dev-sw:1:1)
Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('http://localhost:8100/') with script ('http://localhost:8100/dev-sw.js?dev-sw'): ServiceWorker script evaluation failed

问题原因

  1. VitePWA插件未生效:你的vite.config.ts仅定义了pwaOptions配置对象,但未将VitePWA插件添加到plugins数组中,导致devOptions.type='module'的配置未被应用,浏览器无法识别Service Worker脚本为ES模块。
  2. import.meta.env.DEV兼容性问题:开发环境下,Service Worker模块中import.meta.env的变量识别可能存在延迟,导致条件判断逻辑失效。

解决方案

1. 完善vite.config.ts配置

确保VitePWA插件被正确注册到plugins数组,让配置生效:

import legacy from '@vitejs/plugin-legacy'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
import { VitePWA, VitePWAOptions } from 'vite-plugin-pwa'

const pwaOptions: Partial<VitePWAOptions> = {
  registerType: 'autoUpdate',
  strategies: 'injectManifest',
  srcDir: 'src',
  disable: false,
  filename: 'sw.ts',
  base: '/',
  includeAssets: ['favicon.svg'],
  devOptions: {
    enabled: true,
    type: 'module',
    navigateFallback: 'index.html',
  },
}

// 关键:将VitePWA插件加入plugins数组
export default defineConfig({
  plugins: [react(), legacy(), VitePWA(pwaOptions)],
})

2. 替换Service Worker中的环境判断逻辑

用self.location.hostname判断开发环境,替代import.meta.env.DEV,避免模块环境下的变量识别问题:

import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'
import { clientsClaim } from 'workbox-core'
import { NavigationRoute, registerRoute } from 'workbox-routing'

declare let self: ServiceWorkerGlobalScope

precacheAndRoute(self.__WB_MANIFEST)
cleanupOutdatedCaches()

// 替换import.meta.env.DEV的判断方式
let allowlist: undefined | RegExp[]
if (self.location.hostname === 'localhost') {
  allowlist = [/^\$/]
}

registerRoute(new NavigationRoute(
  createHandlerBoundToURL('index.html'),
  { allowlist },
))

self.skipWaiting()
clientsClaim()

3. 清理缓存并重启服务

  • 在浏览器开发者工具的Application > Service Workers中,卸载已注册的旧Service Worker
  • 按Ctrl+Shift+R强制刷新页面清除缓存
  • 重启Vite开发服务器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:50:09