Next.js + MSW Service Worker Registration Fix Under a basePath
Next.js + MSW Service Worker Registration Fix Under a basePath
Upgrade MSW to 2.6.6.
背景
把 CRA 搬到 Next.js(App Router)後,我的網站部署在 /TeachCertAdm。 MSW 在啟動時一直報錯:
1
2
3
[MSW] Failed to register the Service Worker:
ServiceWorker script at http://localhost:3000/mockServiceWorker.js
for scope http://localhost:3000/ encountered an error during installation.
這代表 SW 嘗試從根目錄 mockServiceWorker.js 註冊,但我的實際路徑在 /TeachCertAdm/ 下,導致路徑與 scope 不匹配。
解法要點
- Next.js 要設 basePath
- 強制 trailing slash(確保 /TeachCertAdm/ 結尾)
- MSW 用 basePath 組出正確的 SW URL 與 scope
設定一:next.config.mjs
1
2
3
4
5
6
7
8
9
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
const nextConfig = {
reactCompiler: true,
basePath,
trailingSlash: true,
};
export default nextConfig;
設定二:.env.local
1
NEXT_PUBLIC_BASE_PATH=/TeachCertAdm
設定三:providers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"use client";
import { useEffect, useState } from "react";
export default function Providers({ children }) {
const [ready, setReady] = useState(process.env.NODE_ENV !== "development");
useEffect(() => {
if (process.env.NODE_ENV !== "development") return;
let active = true;
(async () => {
const { worker } = await import("../mocks/browser");
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
const scope = basePath ? `${basePath}/` : "/";
await worker.start({
serviceWorker: {
url: `${basePath}/mockServiceWorker.js`,
options: { scope },
},
});
if (active) setReady(true);
})();
return () => {
active = false;
};
}, []);
if (!ready) return null;
return children;
}
注意事項
- 開發時網址一定要用
http://localhost:3000/TeachCertAdm/, 結尾一定要有/; - 有改 next.config.mjs 或 .env.local 一定要 重啟 dev server
結論
錯誤的根本原因是 MSW 的 SW 路徑跑到 mockServiceWorker.js,
但實際部署在 /TeachCertAdm 下。
用 basePath + trailingSlash + 正確 scope 就能穩定解決。
This post is licensed under CC BY 4.0 by the author.