Why does workbox-webpack-plugin prepend "auto" to all asset paths? (resulting in 404's when the app starts up)

1.3k views Asked by At

Workbox is driving me bananas. When my app starts, all precached routes return http404, because the workbox InjectManifest plugin appears to prepend "auto" to all the cached urls. I have to idea why it does this. I've tried re-installing npm packages, running in incognito, clearing all caches, etc.

I run the application with "webpack-dev-server --mode development --open", and I get the following warning, which might be part of the problem:

WARNING in InjectManifest has been called multiple times, perhaps due to running webpack in --watch mode. The precache manifest generated after the first call may be inaccurate! Please see https://github.com/GoogleChrome/workbox/issues/1790 for more information.

I don't know why I get this error, because I have set watch:false in my webpack configuration.

Note how all the paths have "auto" in front and return http404. Note that I cleared all caches on Chrome's "Application" tab. The same happens in an incognito tab.

auto paths

When open a new tab and remove the "auto", it works fine:

works fine without auto

The service worker file with the injected manifest shows that "auto" is part of the urls:

enter image description here

Has anyone seen this before? I'm starting to consider writing a service worker from scratch and ditching workbox, but I'd obviously rather use workbox if I can get it to work properly.

The code:

I use the workbox-webpack-plugin to inject the precache manifest in my service worker, like so:

import {precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';

// Use the imported Workbox libraries to implement caching,
// routing, and other logic:
precacheAndRoute(self.__WB_MANIFEST || []);

registerRoute(
    ({request}) => request.destination === 'image',
    new CacheFirst({cacheName: 'images'}),
);

My webpack.config.js looks as follows, nothing fancy:

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

module.exports = {
    watch: false,
    entry: path.resolve(__dirname, './src/index.js'),
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[contenthash].js',
    },
    module: {
        rules: [{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, {
            test: /\.(png|svg|jpg|gif)$/,
            use: [
                'file-loader',
            ],
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Prototype webpack + react + workbox usage',
            template: './src/index.html',
            filename: './index.html',
            'meta': {
                'viewport': 'width=device-width, initial-scale=1.0',
                'charset': 'UTF-8'
            }
        }),
        new InjectManifest({
            swSrc: './service-worker.js',
            swDest: './workbox-sw-generated.js',
        })
    ]
};

My index.html is pretty straight-forward as well:

<!DOCTYPE html>
<html lang="en">

<head>
    <title><%= htmlWebpackPlugin.options.title %></title>
    <script>
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
              navigator.serviceWorker.register('/workbox-sw-generated.js')
            });
        }
    </script>
</head>

<body>
    <section id="index"></section>
</body>

</html>

And here is my package.json:

{
    "name": "simple_webpack_boilerplate",
    "version": "1.0.0",
    "description": "A ready to use simple webpack boilerplate for react",
    "main": "src/index.js",
    "scripts": {
        "start": "webpack-dev-server --mode development --open",
        "build": "webpack --mode production"
    },
    "author": "Willem",
    "license": "ISC",
    "devDependencies": {
        "@babel/core": "7.11.4",
        "@babel/preset-env": "7.11.0",
        "@babel/preset-react": "7.10.4",
        "babel-loader": "8.1.0",
        "file-loader": "^6.1.1",
        "html-webpack-plugin": "4.4.1",
        "terser-webpack-plugin": "^4.1.0",
        "webpack": "^5.0.0",
        "webpack-cli": "^3.3.12",
        "webpack-dev-server": "3.11.0",
        "workbox-webpack-plugin": "^5.1.4"
    },
    "dependencies": {
        "lodash": "^4.17.20",
        "react": "16.13.1",
        "react-dom": "16.13.1",
        "react-router-dom": "^5.2.0"
    }
}
1

There are 1 answers

1
willem On

The problem here was that workbox-webpack-plugin v5 was not compatible with webpack v5, which had just been released. The solution was to use webpack v4 instead.