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

Create React App自定义ServiceWorker编译报错:所有标识符未定义

Fixing "Undefined" Errors in Custom Service Worker for Create React App

I've run into this exact issue before—Create React App's default build pipeline treats every .js file in the src/ directory as application code, so it's transpiling your sw-custom.js with Babel and Webpack, which breaks the Service Worker-specific environment. Here's how to fix it step by step:

Step 1: Move Your Custom Service Worker Out of src/

CRA doesn't process files outside the src/ directory (no extra configuration needed here).

  • Move sw-custom.js from src/sw-custom.js to your project's root directory (same level as package.json).
  • Update your react-build.js to point to the new path:
    swSrc: './sw-custom.js', // Changed from 'src/sw-custom.js'
    

Step 2: Fix Invalid Code in Your Service Worker

Your current sw-custom.js has a critical error that will throw undefined errors even after fixing the build issue:

window.location.reload() doesn't exist in the Service Worker context—there's no window object available here.

Replace that lifecycle code with proper Service Worker handling:

self.addEventListener('install', (event) => {
  self.skipWaiting();
  console.log('Service Worker installed');
});

self.addEventListener('activate', (event) => {
  // Take control of all open clients immediately
  event.waitUntil(clients.claim());
  // Optional: Notify clients to refresh for latest content
  clients.matchAll({ type: 'window' }).then(clients => {
    clients.forEach(client => {
      client.postMessage({ type: 'SW_UPDATED' });
    });
  });
});

You can add code in your React app to listen for this message and trigger a reload if needed:

// In your main App component or index.js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.addEventListener('message', (event) => {
    if (event.data.type === 'SW_UPDATED') {
      if (confirm('New version available! Refresh to update?')) {
        window.location.reload();
      }
    }
  });
}

Step 3: Update the Service Worker Registration Path

Your CRA-generated registration file points to service-worker.js, but your custom build script outputs to sw.js. Update the register function:

// In CRA's service worker registration file
const swUrl = `${process.env.PUBLIC_URL}/sw.js`; // Changed from '/service-worker.js'

Step 4: Verify Your Build Script

Make sure your package.json runs the React build first, then injects the manifest:

"scripts": {
  "build": "react-scripts build && node react-build.js",
  // ... other scripts
}

Final Corrected sw-custom.js

Here's the full fixed version of your custom Service Worker:

if ('function' === typeof importScripts) {
  importScripts(
    'https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js'
  );

  // Global workbox
  if (workbox) {
    console.log('Workbox is loaded');

    // Disable logging
    workbox.setConfig({ debug: false });

    self.addEventListener('install', (event) => {
      self.skipWaiting();
      console.log('Service Worker installed');
    });

    self.addEventListener('activate', (event) => {
      event.waitUntil(clients.claim());
      clients.matchAll({ type: 'window' }).then(clients => {
        clients.forEach(client => {
          client.postMessage({ type: 'SW_UPDATED' });
        });
      });
      console.log('Service Worker activated and controlling clients');
    });

    // Manual injection point for manifest files.
    // All assets under build/ and 5MB sizes are precached.
    workbox.precaching.precacheAndRoute([]);

    // Font caching
    workbox.routing.registerRoute(
      new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
      workbox.strategies.cacheFirst({
        cacheName: 'googleapis',
        plugins: [
          new workbox.expiration.Plugin({
            maxEntries: 30,
          }),
        ],
      })
    );

    // Image caching
    workbox.routing.registerRoute(
      /\.(?:png|gif|jpg|jpeg|svg)$/,
      workbox.strategies.cacheFirst({
        cacheName: 'images',
        plugins: [
          new workbox.expiration.Plugin({
            maxEntries: 60,
            maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
          }),
        ],
      })
    );

    // JS, CSS caching
    workbox.routing.registerRoute(
      /\.(?:js|css)$/,
      workbox.strategies.staleWhileRevalidate({
        cacheName: 'static-resources',
        plugins: [
          new workbox.expiration.Plugin({
            maxEntries: 60,
            maxAgeSeconds: 20 * 24 * 60 * 60, // 20 Days
          }),
        ],
      })
    );
  } else {
    console.error('Workbox could not be loaded. No offline support');
  }
}

These changes will prevent CRA from compiling your Service Worker code, fix the invalid window reference, and ensure your custom Service Worker is registered correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:02:41