React TSX项目转PWA部署Firebase时Service Worker注册失败求助
我将React TSX项目改造为PWA,在src目录添加了Service Worker,执行npm run build后通过firebase deploy部署,出现以下错误:
The script has an unsupported MIME type ('text/html').
react_devtools_backend_compact.js:2367 Service Worker registration failed: DOMException: Failed to register a ServiceWorker for scope ('/') with script.... The script has an unsupported MIME type ('text/html').
项目托管在Firebase,manifest.json、serviceWorker.js与index.tsx同处于src目录,相关文件内容如下:
src/index.tsx
import React from "react" import ReactDOM from "react-dom/client" import "./index.css" import App from "./App" import reportWebVitals from "./reportWebVitals" import * as serviceWorker from "./serviceWorker" // import "bootstrap/dist/css/bootstrap.min.css" // import { AuthProvider } from "./AuthContext" const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) root.render( <React.StrictMode> {/* <AuthProvider> */} <App /> {/* </AuthProvider> */} </React.StrictMode> ) serviceWorker.register() reportWebVitals()
src/serviceWorker.js
export function register() { if ("serviceWorker" in navigator) { window.addEventListener("load", () => { navigator.serviceWorker .register("/service-worker.js") .then((registration) => { console.log("Service Worker registered with scope:", registration.scope) }) .catch((error) => { console.error("Service Worker registration failed:", error) }) }) } } export function unregister() { if ("serviceWorker" in navigator) { navigator.serviceWorker.ready .then((registration) => { registration.unregister() }) .catch((error) => { console.error("Service Worker unregistration failed:", error) }) } }
src/manifest.json
{ "name": "Your App", "short_name": "your-app", "description": "fun app to use", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#007bff", "icons": [ { "src": "./app-icon.png", "sizes": "192x192", "type": "image/png" }, { "src": "./app-icon.png", "sizes": "512x512", "type": "image/png" } ] }
解决指引
问题核心
代码中注册的/service-worker.js并未出现在build目录的根路径,Firebase找不到该文件时返回默认HTML页面,导致MIME类型为text/html,不符合Service Worker的要求。
具体修复步骤
调整Service Worker文件位置:
将service-worker.js从src目录移到public目录,这样npm run build时会直接把文件复制到build根目录,确保Firebase能正确访问到它。修正manifest配置:
- 将
manifest.json也移到public目录。 - 在
public/index.html中添加manifest引用:<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> - 修改manifest里的图标路径为
"/app-icon.png",同时确保app-icon.png放在public目录下。
- 将
重新打包部署:
执行npm run build,检查build目录根目录是否存在service-worker.js和manifest.json,确认无误后再执行firebase deploy。可选:用Workbox简化配置:
Create React App内置Workbox支持,你可以直接启用它自动生成Service Worker:- 在
package.json中添加"workbox": { "skipWaiting": true }配置。 - 或者使用
cra-template-pwa模板的默认配置,它会自动处理Service Worker的打包和注册逻辑,避免路径问题。
- 在
内容的提问来源于stack exchange,提问作者Menachem Angster

