GoogleChrome / workbox

📦 Workbox: JavaScript libraries for Progressive Web Apps
https://developers.google.com/web/tools/workbox/
MIT License
12.34k stars 814 forks source link

ERROR in Can't find self.__WB_MANIFEST in your SW source in TypeScript project #2519

Closed RareSecond closed 4 years ago

RareSecond commented 4 years ago

Library Affected: Current version: 5.1.3

Issue or Feature Request Description: When trying to build my webpack project, I run into the error ERROR in Can't find self.__WB_MANIFEST in your SW source.

I've tried some searching, but all the related issues don't point me in the right direction and the docs are no help either.

webpack.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { InjectManifest } = require('workbox-webpack-plugin');

module.exports = (env = {}) => {
  const mode = env.production ? 'production' : 'development';
  const apiUrl = env.production
    ? 'https://xxx.cloudfunctions.net'
    : 'http://localhost:5001/xxx/us-central1';
  return {
    mode,
    entry: './src/index.tsx',
    output: {
      filename: `main${env.production ? '-[contenthash]' : ''}.js`,
      path: path.resolve(__dirname, 'dist'),
      publicPath: '/',
    },
    resolve: {
      extensions: ['.tsx', '.ts', '.js'],
      alias: { 'react-dom': '@hot-loader/react-dom' },
    },
    module: {
      rules: [
        {
          test: /\.(j|t)sx?$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
          },
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: ['file-loader'],
        },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: 'src/index.html',
      }),
      new webpack.DefinePlugin({
        mode,
        API_URL: JSON.stringify(apiUrl),
      }),
      new InjectManifest({
        swSrc: path.resolve(__dirname, './service-worker.ts'),
      }),
    ],
    devServer: {
      historyApiFallback: true,
    },
  };
};

service-worker.ts

// Listen for install event, set callback
self.addEventListener('install', function (event) {
  console.log('installed');
});

index.ts

...
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/service-worker.js')
      .then((registration) => {
        console.log('SW registered: ', registration);
      })
      .catch((registrationError) => {
        console.log('SW registration failed: ', registrationError);
      });
  });
}
...

However, the process seems to work correctly. When I serve my page, I see the installed console log, and all other project functionality works as well.

Any idea what the root cause of this issue is?

jeffposnick commented 4 years ago

If you'd like to use the InjectManifest plugin, you need to include self.__WB_MANIFEST somewhere in your swSrc file. The InjectManfiest plugin will look for that symbol and replace it with the manifest created as part of the build process—i.e. literally "injecting the manifest" into your swSrc.

You'd normally do something in your swSrc like the following to make use of the manifest:

import {precacheAndRoute} from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST);

// Additional code goes here.

If you don't want to use workbox-precaching, then you don't need to use the InjectManifest plugin at all. You can use any of the other Workbox libraries that you want, and just compile your service-worker.ts as another entry alongside your main entry in webpack. The InjectManifest plugin is only needed if you want to inject the precache manifest.

RareSecond commented 4 years ago

Thanks for the info!

Is this somewhere explained in the docs, or did I simply look over it? Just afraid I might have missed a huge part of the documentation..

FloodGames commented 3 years ago

If you'd like to use the InjectManifest plugin, you need to include self.__WB_MANIFEST somewhere in your swSrc file. The InjectManfiest plugin will look for that symbol and replace it with the manifest created as part of the build process—i.e. literally "injecting the manifest" into your swSrc.

You'd normally do something in your swSrc like the following to make use of the manifest:

import {precacheAndRoute} from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST);

// Additional code goes here.

If you don't want to use workbox-precaching, then you don't need to use the InjectManifest plugin at all. You can use any of the other Workbox libraries that you want, and just compile your service-worker.ts as another entry alongside your main entry in webpack. The InjectManifest plugin is only needed if you want to inject the precache manifest.

Imagine your webapp has a HD and SD version (for example SD for mobile). How do you prevent your precache including both the sd and hd files?

Basically: I only want to cache when a script calls an asset. (and do not want to precache I think)

samgermain commented 3 years ago
import {precacheAndRoute} from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST);

I have this and am still getting this error

samgermain commented 3 years ago

Actually, that is the part which is specifically causing this error I think

tayebehsafdari commented 3 years ago

If you'd like to use the InjectManifest plugin, you need to include self.__WB_MANIFEST somewhere in your swSrc file. The InjectManfiest plugin will look for that symbol and replace it with the manifest created as part of the build process—i.e. literally "injecting the manifest" into your swSrc.

You'd normally do something in your swSrc like the following to make use of the manifest:

import {precacheAndRoute} from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST);

// Additional code goes here.

If you don't want to use workbox-precaching, then you don't need to use the InjectManifest plugin at all. You can use any of the other Workbox libraries that you want, and just compile your service-worker.ts as another entry alongside your main entry in webpack. The InjectManifest plugin is only needed if you want to inject the precache manifest.

Thank you :)

markgong-gd commented 2 years ago

i set import {precacheAndRoute} from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST);

error show : Can't find self.__WB_MANIFEST in your SW source