Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to register service worker using webpack?

I'm implementing a ReactJS web application using webpack and I want to start implementing a service worker to handle the network calls, in order to cache files. However, I find it hard to register the service worker javascript file. (I should add that I'm a beginner when it comes to both React and webpack.)

If I get it right, webpack merges every javascript file into one bundle.js file, which makes it hard to call navigator.serviceWorker.register('./sw.js').... I have tried different approaches, such as serviceworker-webpack-plugin, but without luck. If I follow the steps provided on the readme page, I get an error message saying Uncaught Error: serviceworker-webpack-plugin: It seems that your are importing "serviceworker-webpack-plugin/lib/runtime" without using the plugin. Makes sure that your webpack configuration is correct..

Here's my webpack.config.js file:

var webpack = require('webpack');
var path = require('path');
import ServiceWorkerWebpackPlugin from 'serviceworker-webpack-plugin';

module.exports = {
  devtool: 'inline-source-map',
  entry: [
    'webpack-dev-server/client?http://127.0.0.1:8080/',
    'webpack/hot/only-dev-server',
    './src/index.js'
  ],
  output: {
    path: path.join(__dirname, 'public'),
    filename: 'bundle.js'
  },
  resolve: {
    modulesDirectories: ['node_modules', 'src'],
    extensions: ['', '.js']
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: ['babel-loader'],
        query: {
          presets: ['es2015','react']
        }
      }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    new ServiceWorkerWebpackPlugin({
      entry: path.join(__dirname, 'src/sw.js'),
      excludes: [
        '**/.*',
        '**/*.map',
        '*.html',
      ],
      filename: 'sw.js'
    })
  ]
}

Note: I used the create-react-app command to get going. Also, I have no issues with the service worker itself, I have a working implementation for another web app. It's just registering it I'm struggling with.

Any help is appreciated!

like image 690
Göran Lilja Avatar asked Dec 14 '16 19:12

Göran Lilja


People also ask

How do I register a service worker in webpack?

Create a project with create-react-app and then do some changes in package. json for adding service worker in your project.

What is workbox webpack plugin?

Workbox provides two webpack plugins: one that generates a complete service worker for you and one that generates a list of assets to precache that is injected into a service worker file. The plugins are implemented as two classes in the workbox-webpack-plugin module, named GenerateSW and InjectManifest .

What is PWA webpack?

Progressive Web Applications (or PWAs) are web apps that deliver an experience similar to native applications.

How to integrate WebPack with workbox service worker?

Workbox has a great support for it. In particular for the precache phase, there is the npm package workbox-webpack-plugin that contains a plugin called InjectManifest. This plugin is able to inject in the Service Worker code a variable named __WB_MANIFEST that contains a list of the entry points/generated files of the Webpack bundling process.

Can I use web workers without a worker-loader in Webpack?

As of webpack 5, you can use Web Workers without worker-loader. The syntax was chosen to allow running code without bundler, it is also available in native ECMAScript modules in the browser. Similar syntax is supported in Node.js (>= 12.17.0):

What does serviceworker-Webpack-plugin do?

serviceworker-webpack-plugin also provides a way for the serviceworker to see a list of all the bundle files it should cache, but that functionality is not available directly and requires making a webpack plugin to get.

What is a progressive web application (PWA)?

Progressive Web Applications (or PWAs) are web apps that deliver an experience similar to native applications. There are many things that can contribute to that. Of these, the most significant is the ability for an app to be able to function when offline. This is achieved through the use of a web technology called Service Workers.


1 Answers

To remove the error, change the

import ServiceWorkerWebpackPlugin from 'serviceworker-webpack-plugin';

to

var ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');

Also note that the documentation has a typo:

plugins: [
new ServiceWorkerWebbackPlugin({
  entry: path.join(__dirname, 'src/sw.js'),
}),
],

Notice that Webpack is spelled incorrectly here. It should be Webpack instead of Wepback.

Also, the docs stated that to register the Service Worker on main JS thread using the following code:

import runtime from 'serviceworker-webpack-plugin/runtime';

if ('serviceWorker' in navigator) {
  const registration = runtime.register();
}

However, upon closer inspection, it seems that the runtime directory is wrong. Checking the node_modules folder,

runtime location

It seems that the runtime.js is inside the lib folder. So, to fix this, change the

import runtime from 'serviceworker-webpack-plugin/runtime';

to

import runtime from 'serviceworker-webpack-plugin/lib/runtime';

Once I did this, I managed to get the Service Worker installed on my dev environment.

sw.js

I'm still learning React + Webpack though! Also still figuring out a way to use Service Worker properly in my React app. I've also informed the author of this plugin of these required changes in the documentation. Hope it helps others!

like image 108
Nicholas Lie Avatar answered Sep 20 '22 21:09

Nicholas Lie