Workbox-webpack-plugin未适配output.publicPath,Service Worker加载路径异常
The core issue here is that your site lives in a subdirectory (https://test.com/custom/), but Workbox's default GenerateSW configuration assumes a root-domain deployment. This causes mismatched paths for both the sw.js file itself and the cached resources it references. Here's how to fix it:
Step-by-Step Adjustments
1. Rewrite Resource Path Prefixes
Add the modifyURLPrefix option to map the root-relative paths Workbox generates to your actual subdirectory. This ensures all cached assets point to the correct location under /custom/.
2. Explicitly Define the Service Worker Scope
While the SW's scope defaults to the directory it’s hosted in (/custom/ when sw.js is at /custom/sw.js), explicitly setting it eliminates ambiguity, especially if you have nested routes.
3. Configure Navigation Fallback (Optional for SPAs)
If you’re building a single-page app, set navigateFallback to your entry HTML’s subdirectory path to handle direct route access correctly.
Updated Workbox Configuration
new WorkboxPlugin.GenerateSW({ globDirectory: outputDir, globPatterns: ['**/*.{html,js}'], swDest: path.join(outputDir, 'sw.js'), clientsClaim: true, skipWaiting: true, // Map root-relative paths to your subdirectory modifyURLPrefix: { '/': '/custom/' }, // Explicitly set the SW's control scope scope: '/custom/', // Optional: Route fallback for SPA navigation navigateFallback: '/custom/index.html', runtimeCaching: [ { urlPattern: new RegExp('cdn.test.com/'), handler: 'CacheFirst' } ] })
4. Fix Service Worker Registration
Double-check your client-side registration code points to the correct subdirectory path for sw.js:
if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/custom/sw.js') .then(registration => console.log('SW registered successfully:', registration)) .catch(error => console.error('SW registration failed:', error)); }); }
Why This Works
modifyURLPrefixrewrites cached resource paths (e.g., from/app.jsto/custom/app.js) to match your deployment structure.- The
scopesetting ensures the Service Worker only manages resources under/custom/, avoiding unintended control over other parts of the domain. - Correct registration path ensures the browser fetches sw.js from
https://test.com/custom/sw.jsinstead of the root domain.
内容的提问来源于stack exchange,提问作者thecodejack

