facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.73k stars 26.85k forks source link

Can't find self.__WB_MANIFEST in your SW source. #10437

Closed ernestostifano closed 3 years ago

ernestostifano commented 3 years ago

Describe the bug

Whenever I try to build my App using yarn build, it fails after some seconds giving me the following output:

yarn run v1.22.10
$ react-scripts build
Creating an optimized production build...
Failed to compile.

Can't find self.__WB_MANIFEST in your SW source.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Did you try recovering your dependencies?

Yes.

Which terms did you search for in User Guide?

Read it all.

Environment

Need to install the following packages:
  create-react-app
Ok to proceed? (y) y

Environment Info:

  current version of create-react-app: 4.0.1
  running from /Users/ernestostifano/.npm/_npx/c67e74de0542c87c/node_modules/create-react-app

  System:
    OS: macOS 10.15.7
    CPU: (8) x64 Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz
  Binaries:
    Node: 15.6.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.4.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 87.0.4280.88
    Edge: Not Found
    Firefox: 84.0.2
    Safari: 14.0.1
  npmPackages:
    react: ^17.0.1 => 17.0.1 
    react-dom: ^17.0.1 => 17.0.1 
    react-scripts: 4.0.1 => 4.0.1 
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

I just tried to run yarn build on a non ejected React App with the above specified dependencies and environment conditions.

Please note that yarn start is working just fine.

Expected behavior

Build to succeed.

Actual behavior

Build failed as specified above.

Reproducible demo

N/A.

gustavopch commented 3 years ago

Apparently, CRA v4 changed how it implements the service worker. If you don't need it, just delete the file and the references to it (in my case, that did the job). If you do need the service worker, take a look at https://github.com/cra-template/pwa to analyze how the implementation changed and bring those changes to your own project.

ernestostifano commented 3 years ago

Hi @gustavopch, thank you very much for your response. The problem is gone!

I created a temporary React App using npx create-react-app to see better what the new template was generating.

At the end, I removed the Service Worker file and references and then added the new Report Web Vitals file, references and dependencies.

Everything is working as expected. Thank you again.

ssolders commented 3 years ago

Hi, ran into the same issue and resolved it by creating a new CRA from scratch and took the serviceWorker files + setup from the new one into my existing project.

npx create-react-app my-app --template cra-template-pwa-typescript

Copied serviceWorker.ts and serviceWorkerRegistration.ts to /src and changed the import in index.tsx to

import * as serviceWorkerRegistration from './serviceWorkerRegistration';

// your index.tsx

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorkerRegistration.unregister()

Never got to the bottom of the main cause for the issue - the existing project was created using CRA early may 2021.

serviceWorkerRegistration.ts

// This optional code is used to register a service worker.
// register() is not called by default.

// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.

// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://cra.link/PWA

const isLocalhost = Boolean(
  window.location.hostname === 'localhost' ||
    // [::1] is the IPv6 localhost address.
    window.location.hostname === '[::1]' ||
    // 127.0.0.0/8 are considered localhost for IPv4.
    window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
);

type Config = {
  onSuccess?: (registration: ServiceWorkerRegistration) => void;
  onUpdate?: (registration: ServiceWorkerRegistration) => void;
};

export function register(config?: Config) {
  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
    // The URL constructor is available in all browsers that support SW.
    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
    if (publicUrl.origin !== window.location.origin) {
      // Our service worker won't work if PUBLIC_URL is on a different origin
      // from what our page is served on. This might happen if a CDN is used to
      // serve assets; see https://github.com/facebook/create-react-app/issues/2374
      return;
    }

    window.addEventListener('load', () => {
      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;

      if (isLocalhost) {
        // This is running on localhost. Let's check if a service worker still exists or not.
        checkValidServiceWorker(swUrl, config);

        // Add some additional logging to localhost, pointing developers to the
        // service worker/PWA documentation.
        navigator.serviceWorker.ready.then(() => {
          console.log(
            'This web app is being served cache-first by a service ' +
              'worker. To learn more, visit https://cra.link/PWA'
          );
        });
      } else {
        // Is not localhost. Just register service worker
        registerValidSW(swUrl, config);
      }
    });
  }
}

function registerValidSW(swUrl: string, config?: Config) {
  navigator.serviceWorker
    .register(swUrl)
    .then((registration) => {
      registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        if (installingWorker == null) {
          return;
        }
        installingWorker.onstatechange = () => {
          if (installingWorker.state === 'installed') {
            if (navigator.serviceWorker.controller) {
              // At this point, the updated precached content has been fetched,
              // but the previous service worker will still serve the older
              // content until all client tabs are closed.
              console.log(
                'New content is available and will be used when all ' +
                  'tabs for this page are closed. See https://cra.link/PWA.'
              );

              // Execute callback
              if (config && config.onUpdate) {
                config.onUpdate(registration);
              }
            } else {
              // At this point, everything has been precached.
              // It's the perfect time to display a
              // "Content is cached for offline use." message.
              console.log('Content is cached for offline use.');

              // Execute callback
              if (config && config.onSuccess) {
                config.onSuccess(registration);
              }
            }
          }
        };
      };
    })
    .catch((error) => {
      console.error('Error during service worker registration:', error);
    });
}

function checkValidServiceWorker(swUrl: string, config?: Config) {
  // Check if the service worker can be found. If it can't reload the page.
  fetch(swUrl, {
    headers: { 'Service-Worker': 'script' },
  })
    .then((response) => {
      // Ensure service worker exists, and that we really are getting a JS file.
      const contentType = response.headers.get('content-type');
      if (
        response.status === 404 ||
        (contentType != null && contentType.indexOf('javascript') === -1)
      ) {
        // No service worker found. Probably a different app. Reload the page.
        navigator.serviceWorker.ready.then((registration) => {
          registration.unregister().then(() => {
            window.location.reload();
          });
        });
      } else {
        // Service worker found. Proceed as normal.
        registerValidSW(swUrl, config);
      }
    })
    .catch(() => {
      console.log('No internet connection found. App is running in offline mode.');
    });
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready
      .then((registration) => {
        registration.unregister();
      })
      .catch((error) => {
        console.error(error.message);
      });
  }
}