MacPrawn's avatar

Using hotreload with workbox-webpack-plugin

Anyone has any experience setting-up for development using laravel-mix/webpack, hot-reload and workbox-webpack-plugin? I'm trying not to have to manually call npm run dev on the command line every time I make a change to my javascript code, but still have my service-worker running for testing... Possible?

Thanks!

0 likes
2 replies
MacPrawn's avatar

Thanks - I had found this gist, but it's not really working as is. (as the other user's comment says, it needs to be updated)

But you kind of gave me a direction to go: if you pointed me o this, it must be part of the answer.

I finally got it working with:

./webpack.mix.js

const { mix } = require('laravel-mix');
const { InjectManifest } = require('workbox-webpack-plugin');
const inProduction = mix.inProduction();
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

let webpackConfig = {
    plugins: [
        new InjectManifest({
            swSrc: path.join(`${__dirname}/resources/assets/js`, 'source-sw.js'),
            swDest: path.join(`${__dirname}/public`, 'service-worker.js'),
            globDirectory: '.',
            globIgnores: ['public/*.map', 'public/manifest.json', 'public/mix-manifest.json', 'public/*.config'],
            globPatterns: ['public/*.{js,png,php,css}', 'public/images/*.{png,jpg,jpeg}', 'public/fonts/*'],
            templatedUrls: {
                '/': 'resources/views/layouts/app.blade.php'
            },
            modifyUrlPrefix: {
                'public': ''
            }
        })
    ]
};
/*
webpackConfig.plugins.push(
    new BundleAnalyzerPlugin({
        analyzerMode: 'static',
        reportFilename: path.join(`${__dirname}/public`, 'webpack-report.html'),
        openAnalyzer: false,
        logLevel: 'silent'
    })
);
*/

if(inProduction) {
    webpackConfig.output = { filename: '[name].js', chunkFilename: 'js/[name].app.js', publicPath: '' };
    mix.extract(['vue', 'vuex', 'vue-router', 'axios', 'lodash', 'moment', 'numeral']);
}

mix.js('resources/assets/js/app.js', 'public/js')
    .sass('resources/assets/sass/app.scss', 'public/css/app.css');

mix.webpackConfig(webpackConfig);
    
if(inProduction) mix.disableNotifications();

mix.copy('resources/assets/manifest.json', 'public/manifest.json')
    .copy('resources/assets/images', 'public/images')
    .copy('resources/assets/fonts', 'public/fonts');

if(inProduction) mix.version();
else if(inDevelopment) mix.sourceMaps();

./resources/assets/js/source-sw.js

workbox.skipWaiting();
workbox.clientsClaim();

// make sure we grab from cache if no network
workbox.routing.registerRoute(
  function({ url, event }) {
    return !url.pathname.match(/^\/api\//)
  },
  workbox.strategies.staleWhileRevalidate()
);
workbox.routing.registerRoute(
    new RegExp('.(?:js|css|ico)$'),
    workbox.strategies.networkFirst({
        cacheName: 'static'
    }),
)
workbox.routing.registerRoute(
    new RegExp('.(?:jpg|png|gif|svg)$'),
    workbox.strategies.cacheFirst({
        cacheName: 'images',
        plugins: [
            new workbox.expiration.Plugin({
                maxEntries: 20,
                purgeOnQuotaError: true,
            })
        ]
    })
)

workbox.precaching.precacheAndRoute(self.__precacheManifest);

Hope this helps others!

Please or to participate in this conversation.