Git Product home page Git Product logo

serviceworker-webpack-plugin's Introduction

serviceworker-webpack-plugin

Simplifies creation of a service worker to serve your webpack bundles.

npm version npm downloads Build Status

Dependencies DevDependencies

Installation

npm install serviceworker-webpack-plugin

The problem solved

When building a service worker, you probably want to cache all your assets during the install phase. But in order to do so, you need their names. That's not simple when you are using Webpack:

  • The assets names are non-deterministic when taking advantage of the long term caching.
  • The assets list can even evolve over time as you add splitting points or more resources.
  • You want to be able to use your service worker with the dev-server mode of Webpack.
  • You want to keep the build process as simple as possible.

Setup

1. Add the plugin to your webpack config

import ServiceWorkerWebpackPlugin from 'serviceworker-webpack-plugin';

...

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

2. Register the service worker in your main JS thread

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

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

3. Write your own sw.js

You can now use the global serviceWorkerOption variable in your sw.js. E.g. In our example this object looks like:

{
  assets: [
    './main.256334452761ef349e91.js',
  ],
}

Simple example

You can have a look at the /docs folder if you need a full working example.

API

ServiceWorkerWebpackPlugin(options)

  • options
  • entry, required, string: Path to the actual service worker implementation.
  • filename, string, default 'sw.js': Relative (from the webpack's config output.path) output path for emitted script.
  • excludes, array, default ['**/.*', '**/*.map']: Exclude matched assets from being added to the serviceWorkerOption.assets variable. (Blacklist)
  • includes, array, default ['**/*']: Include matched assets added to the serviceWorkerOption.assets variable. (Whitelist)
  • publicPath, string, default '/': Specifies the public URL address of the output files when referenced in a browser. We use this value to load the service worker over the network.
  • template, function, default noop: This callback function can be used to inject statically generated service worker. It's taking a serviceWorkerOption argument and must return a promise.
  • transformOptions, function: This callback function receives a raw serviceWorkerOption argument. The jsonStats key contains all the webpack build information.
  • minimize: Whether to minimize output. Defaults to process.env.NODE_ENV === 'production'

runtime(options)

Credit

Why simply not use the offline-plugin?

I wouldn't have been able to write this plugin without the offline-plugin project. Thanks @NekR for sharing it!

Still, soon after using it, I realized that it wasn't what I was looking for.

  • The abstraction provided was too high. (I needed to build some custom fetch logic.)
  • It was making me, even more, dependent on Webpack. (What if later, I want to switch to another build system?)

Hence, I decided to change the approach and created this thin layer on top of Webpack to solve the assets name issue. Nothing more.

If you don't care about my two issues with offline-plugin then you don't need to use this package, offline-plugin is great.

The specs

License

MIT

serviceworker-webpack-plugin's People

Contributors

apapirovski avatar guidobouman avatar melvey avatar oliviertassinari avatar oller avatar sabinmarcu avatar shidhincr avatar woutervanvliet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serviceworker-webpack-plugin's Issues

Serious issues with sourcemaps and multiple webpack configs.

I tried playing around with this plugin over the weekend and ran into a few issues. One was just getting a better understanding of service workers :), but it was really hard to do because sourcemaps are completely borked because of the way this plugin operates.

So I did a bit of tinkering around, and I found out a few things.

  1. Don't make your service worker an entrypoint in your main webpack config.
    It's way better to eliminate a bunch of the noise from other plugins that aren't intended to mess
    around with service worker code. Also, from what I read, you really don't want the sw.js filename
    changing with a hash every build, and you're probably using those (hashes) in your prod config.
    // webpack.config.js
    module.exports = [
      {
         // your main code for the page and all your plugins
      },
      {
         // your service worker code, and its plugins.
      }
    ]
  2. You shouldn't be rewriting any source before it goes through babel, or the minifier. The best place to
    put that is in a loader. (just like babel!)
    // in the service worker webpack config
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: [
            { loader: "babel-loader" },
            { loader: "asset-loader" }, // <-- This is the loader I made to do the asset injection.
          ],
        },
      ],
    },      
  3. Multiple configs totally makes it harder to get the assets you want to cache! So I made a new plugin:
    // in the main webpack config
    plugins: [
      {
        apply: compiler => {
          compiler.plugin("done", ({ compilation }) => {
            global.assets = Object.keys(compilation.assets);
          });
        },
      },
    ],
    Cool... so I've squirreled away, in a really hackey way, the assets for the main layer! But the service
    worker config finishes waaaaaaay before the main one... so here's another small hack, and my loader.
    // asset-laoder.js
    module.exports = function(source) {
      const callback = this.async();
      const interval = setInterval(() => {
        if (!global.assets) return; // just wait till the main config is done compiling.
        clearInterval(interval);
        const assets = global.assets.map(asset => `/${asset}`);
        callback(null, source.replace(/'\{assets\}'/ig, JSON.stringify(assets)));
      }, 100);
    };
    // worker.js
    const filesToCache = '{assets}'
    .filter(asset => !asset.endsWith('map') && !asset.endsWith('manifest')); // I don't want to cache those.

Unexpected using UglifyJSPlugin in development mode

Webpack 4
I try to use plugin in development mode and got the error:

			throw new RemovedPluginError(errorMessage);
			^

Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
    at Object.get [as UglifyJsPlugin] (D:\Projects\kometa_old\node_modules\webpack\lib\webpack.js:166:10)

ok, let it doesn't work in prod mode due to using deprecated UglifyJs, but why it uses UglifyJs in dev mode?

Unhandled promise rejection

When I am using this plugin, I keep getting

(node:29634) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): undefined
Can someone suggest an answer ?

service worker not updated

Hello!

i wrote service worker and load it using your plugin success. But when i change my code in sw.js it doesn't updated in browser until i open devtool and force update it by devtools/Application/update or update on reload

i tried reload page 10+ times. Anyway get the first version of service worker as active and none others as installing or waiting

Thanks

Specifying a filename with [hash]

My webpack plugin configuration for this plugin is the following:

new ServiceWorkerWebpackPlugin({
      entry: path.join(__dirname, "src/scripts/sw.js"),
      filename: "sw.[hash:8].js"
    })

This generates everything "correctly" except that in the build I have the following error:

ERROR in ServiceWorkerPlugin: the `entry` option is incorrect.

This is the guilty part:

compilation.errors.push(new Error('ServiceWorkerPlugin: the `entry` option is incorrect.'))

I use a filename with a [hash] and the code expects the compilation.assets result object to contain the sw.[hash:8].js which obviously it won't because it will be something like sw.3cdaa7e5.js.

I understand the aim of testing if the resulting file is there but isn't there another way? Doesn't it fail somewhere else in the code?

DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead

Hi,

I'm trying run my webpack config but it seems that your plugins is using an old version and is now deprecated.

Here's the deprecation trace from my console:

npm run build

> [email protected] build /Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1
> webpack --mode production

(node:58909) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
    at ServiceWorkerPlugin.apply (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/serviceworker-webpack-plugin/lib/index.js:84:16)
    at webpack (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/webpack.js:37:12)
    at processOptions (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:436:16)
    at yargs.parse (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:512:3)
    at Object.parse (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/node_modules/yargs/yargs.js:552:18)
    at /Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:217:8
    at Object.<anonymous> (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:514:3)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)
    at Object.<anonymous> (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/bin/webpack.js:80:2)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:695:10)
    at startup (internal/bootstrap/node.js:201:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)
(node:58909) DeprecationWarning: Tapable.apply is deprecated. Call apply on the plugin directly instead
    at ServiceWorkerPlugin.handleMake (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/serviceworker-webpack-plugin/lib/index.js:122:21)
    at /Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/serviceworker-webpack-plugin/lib/index.js:104:15
    at AsyncParallelHook.eval [as callAsync] (eval at create (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:13:1)
    at AsyncParallelHook.lazyCompileHook [as _callAsync] (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/Hook.js:35:21)
    at hooks.beforeCompile.callAsync.err (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:476:20)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/Hook.js:35:21)
    at Compiler.compile (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:469:28)
    at readRecords.err (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:220:11)
    at Compiler.readRecords (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:342:11)
    at hooks.run.callAsync.err (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:217:10)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/Hook.js:35:21)
    at hooks.beforeRun.callAsync.err (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:214:19)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:15:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/tapable/lib/Hook.js:35:21)
    at Compiler.run (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/lib/Compiler.js:211:24)
    at processOptions (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:509:20)
    at yargs.parse (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:512:3)
    at Object.parse (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/node_modules/yargs/yargs.js:552:18)
    at /Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:217:8
    at Object.<anonymous> (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack-cli/bin/webpack.js:514:3)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)
    at Object.<anonymous> (/Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/webpack/bin/webpack.js:80:2)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:695:10)
Error: Something went wrong during the make event.
    at /Users/dulac/Desktop/CloudStation/WebWork/Udacity/mws-restaurant-stage-1/node_modules/serviceworker-webpack-plugin/lib/index.js:107:20
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:182:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:697:11)
    at startup (internal/bootstrap/node.js:201:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `webpack --mode production`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Don't detect minification using webpack.optimize

In https://github.com/oliviertassinari/serviceworker-webpack-plugin/blob/master/src/index.js#L171-L173

With the new webpack, using this expression:

 return plugin instanceof webpack.optimize.UglifyJsPlugin

Will throw:

RemovedPluginError: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.

This should be change based on the version of webpack.

let minify;
if (Number(webpack.version[0]) >= 4) {
  minify = compiler.options.optimization && compiler.options.optimization.minimize
} else {
   minify = (compiler.options.plugins || []).some(plugin => {
      return plugin instanceof webpack.optimize.UglifyJsPlugin
    })
}

[webpack 4] Build failing due to removed UglifyJsPlugin

Environment

  • Windows 10
  • npm 6.0
  • node 10.1.0
  • webpack 4.5.0
  • webpack-cli 2.0.14
  • serviceworker-webpack-plugin 0.2.3

Steps to reproduce

  1. Install webpack 4
  2. Include the default config of the serviceworker plugin as provided by the documentation
  3. Start a webpack build

Actual result

The build fails with the following error:
Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.

Expected result
The build does not fail due to removed plugins.

Potential solution
Since webpack 4 uses the mode option in conjunction with optimization.minimize, I would suggest to either minify the service-worker assets based on either the mode being set to production or make the minification configurable (minify: true).

Getting a warning for setting publicPath and filename

Here is my config:

        new ServiceWorkerWebpackPlugin({
            entry: join(__dirname, 'src/service-worker.ts'),
            filename: 'service-worker.js',
            publicPath: '/dist/',
        }),
ServiceWorkerPlugin: publicPath is used in conjunction with relativePaths,
          publicPath was set by the ServiceWorkerPlugin to empty string

How can I make the config go away?

Thank you

Not really an issue - just wanted to thank you for this plugin! ๐ŸŽ† (Didn't know where else to thank you).

It's lightweight!

I agree with your points.

The issue with other plugins (which are really powerful) is that it is a bit too abstract for me, also couples us to webpack.

However, I've tried rolling my own implementation and hit the same problems you've listed in your README.

Good work! I will hopefully be using this plugin in the projects I'm involved in once I experiment around with this more! (Initial set up locally works great!) ๐ŸŽ‰

Module not found: Error: Can't resolve 'serviceworker-webpack-plugin/lib/runtime'

I Register the service worker in the main JS thread:
import runtime from 'serviceworker-webpack-plugin/lib/runtime';

errors as follows

ERROR in ./src/views/index/index.js
Module not found: Error: Can't resolve 'serviceworker-webpack-plugin/lib/runtime' in '/Users/XXX/front-end/webapps/src/views/index'
 @ ./src/views/index/index.js 43:15-66
 @ ./src/route/menuroutedata.js
 @ ./src/route/index.js
 @ ./src/index.js
 @ multi webpack-hot-middleware/client ./src/index

but I have already install the pulgin,
image

thanks a lot

How to start demo app in doc/

Hi there is no package.json file nor execution scripts in the root of docs. Could you explain me that how to use it to start the application

Multiple workers

Hi!

First at all, thank you for this great plugin you made available for all of us.

I would like to register a second service worker (for firebase messaging) but I can't find an ideal solution that works well with webpack. I need to import some of the assets from webpack on this secondary service worker, but this seems an impossible mission.

If I instantiate twice the plugin on webpack, there's no way to register them both independently from the app (runtime.register()).

Thank you in advance.

Accessing serviceWorkerOption in sw.js

Webpack v2.2.0-rc.1
sw.js
console.log(global.serviceWorkerOption) //Gives undefined

Generated sw.js after webpack build

/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.l = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };

/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};

/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};

/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "/static/";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {

var g;

// This works in non-strict mode
g = (function() { return this; })();

try {
	// This works if eval is allowed (see CSP)
	g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
	// This works if the window reference is available
	if(typeof window === "object")
		g = window;
}

// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}

module.exports = g;


/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(global) {

//Accessing Service Worker assets
console.log(global.serviceWorkerOption);
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }
/******/ ]);


Get publicPath at runtime with file://

Config 1

My webpack config is

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

which ouputs a sw.js file in a build/ folder.

I then run Electron, which loads a .html file via the file:// protocol. The bundled js loads file:///sw.js, and I get a network error saying the service worker file cannot be fetched.

Config 2

I change the webpack config to:

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

When I run electron, the bundled js loads file:///Users/amaurymartiny/path/to/build/sw.js, which is correct, and my service worker is loaded.

However this path is hardcoded into the bundled js, since it's done at compile time, so if I package the electron app and run it on another computer, I get another sw file cannot be fetched error.

Question

Is it possible to set the path of sw.js at runtime?

Fails in webpack 4 with UglifyJsPlugin

Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
node_modules/serviceworker-webpack-plugin/lib/index.js:198:61

sw.js in TypeScript?

Would it be possible to write the sw.js file in TypeScript. I need to import some parts of my app which is in TS.

Support Webpack 3

Webpack 3 was just released, and it shouldn't have any breaking changes for this plugin. You should be able to just add it as another version in peerDependencies.

I'll submit a PR to add it into the package.json later today.

[ES5] not working with require

Hi i am trying to use your plugin but i'm not using es6 in my webpack set up and when i attempt to use it via require i get the following message:

TypeError: ServiceWorkerWepbackPlugin is not a constructor

Any Help would be Greatly Appreciated

Service worker cache serving old files and not updating.

Hello
I could really use some advice about initializing the service worker cache logic.
Right now the service worker installs and activates nicely when I clean the cache manually in browser.
But after the first installation the service worker always loads the first installed files.
const { assets } = global.serviceWorkerOption; << Shows the most updated assets but it does not serve them.

And I deploy the SW in index.js :
if (process.env.NODE_ENV === "production" && 'serviceWorker' in navigator) { const runtime = require('serviceworker-webpack-plugin/lib/runtime'); const registration = runtime.register(); }

My sw.js is pretty much a copy-paste from the docs:
https://paste.ofcode.org/aTrM9Z98ruHCfRdFrn8866

Thanks in advance for any feedback

Install with Quasar-Framework

I'm trying to use this with the Quasar-Framework (https://github.com/quasarframework/quasar) but don't seem to have access to the webpack config file.

Any suggestion on how to integrate this into that environment?

The closest config seems to be the .babelrc file which is:

{
  "presets": [["es2015", {"modules": false}], "stage-2"],
  "plugins": ["transform-runtime"],
  "comments": false
}

As you can tell, I'm out of my element when it comes to webpack...

The script has an unsupported MIME type ('text/html')

I've got this error using webpack 4 and serviceworker-webpack-plugin alpha 2

The script has an unsupported MIME type ('text/html').
Failed to load resource: net::ERR_INSECURE_RESPONSE

{
  "code": "messaging/failed-serviceworker-registration",
  "message": "Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html'). (messaging/failed-serviceworker-registration).",
  "browserErrorMessage": "Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html')."
}

webpack 4 support

it is not working well with webpack 4

any plans to release a new version with wepback 4 support?

Example: Fallback to './' upon navigate mode?

Thank's for a great example to getting started using service workers. I just got a question regarding the following part:

      .catch(() => {
        // User is landing on our page.
        if (event.request.mode === 'navigate') {
          return global.caches.match('./')
        }

        return null
      })

Why do we fall back to global.caches.match('/') upon navigate? What is the "expected" scenario that this will happen? If we have / cached, it will be returned immediately, or am I missing something?

Is there a way to add babel-polyfill using options ?

Thanks guys for all the work done !

To use ES6 features like async/await i have to import babel-polyfill before using my ES6 code.

serviceWorker/index.js:

import 'babel-polyfill';
import './worker';

serviceWorker/worker.js:

async function myAsyncStuffHere() {}

Is there a way to provide babel-polyfill on the entry options or something like that as we can do on webpack ?

ERROR in ServiceWorkerPlugin: the `entry` option is incorrect.

i am using service worker plugin in my web pack project, getting error as
ERROR in ServiceWorkerPlugin: the entry option is incorrect.
Child serviceworker-plugin:

ERROR in ./src/sw.js
Module parse failed: /Users/praveenkumar/Downloads/git/sunmool.client/src/sw.js Unexpected token (5:0)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (5:0)
    at Parser.pp$4.raise (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:2221:15)
    at Parser.pp.unexpected (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:603:10)
    at Parser.pp$3.parseExprAtom (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1822:12)
    at Parser.pp$3.parseExprSubscripts (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1715:21)
    at Parser.pp$3.parseMaybeUnary (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1692:19)
    at Parser.pp$3.parseExprOps (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1637:21)
    at Parser.pp$3.parseMaybeConditional (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1620:21)
    at Parser.pp$3.parseMaybeAssign (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1597:21)
    at Parser.pp$3.parseExpression (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:1577:63)
    at Parser.pp$1.parseStatement (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:727:47)
    at Parser.pp$1.parseLabeledStatement (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:958:22)
    at Parser.pp$1.parseStatement (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:729:21)
    at Parser.pp$1.parseBlock (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:981:25)
    at Parser.pp$1.parseStatement (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:709:33)
    at Parser.pp$1.parseTopLevel (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:638:25)
    at Parser.parse (/Users/praveenkumar/Downloads/git/sunmool.client/node_modules/webpack/node_modules/acorn/dist/acorn.js:516:17)

Specify output `path` folder

I'm working with React app where all the bundled files going to a build folder but I want to be able to set the service worker file to the root public folder.

I can specify filename: '../service-worker.js', but when using webpack dev server, this breaks.

Would it be possible to add something like path: path.join(__dirname, 'public') to the config?

Thanks (and great work with the plugin, it's saved my so many headaches!)

How to use this plugin with webpack-dev-server

Hi!

I'm wondering how to use this plugin with webpack-dev-server? I get this to work beautifully when applying production builds using webpack -p build command, but when I try to use this with dev-server, the client will not naturally find the output js-file (hence -it's not actually produced in server-mode)

Here's my current plugins and their settings:

plugins: [ 
  new BundleAnalyzerPlugin(),
  new ServiceWorkerWebpackPlugin({
    entry:    `${APP_DIR}/service-worker.js`,
    filename: "../service-worker.js",
    excludes: [ "**/.*", "**/*.map", "*.html" ],
   })
  new webpack.NamedModulesPlugin(), // Named Modules for DEV:
  new webpack.HotModuleReplacementPlugin(),
  new webpack.optimize.CommonsChunkPlugin({
    name: [ "vendor", "polyfills" ]
  }),
  new HtmlWebpackPlugin({
    filename: 	       "../index.html",
    title:             "Learning Diary Project",
    template:          `${APP_DIR}/index.ejs`,
    alwaysWriteToDisk: true
  }),
  new HtmlWebpackHarddiskPlugin(),
 ]

Fails and hangs if filename contains a '[hash]'

Currently, the plugin only looks for assets with the exact same name mentioned in the config file. But if a hash is included in the filename, the plugin won't be able to find it.

This results in a unhandled promise rejection, and the compilation hangs. It seems that the callback is never called if that problem happens. That may be related to #19.

Message handling

Can't send message to service worker from window and can't handle message in window from service worker. Is there any options to handle it?

I use handler in service worker:
self.addEventListener('message', (event) => { debugger; });

And post message using:
navigator.serviceWorker.controller.postMessage("ololo");

And nothing.

Avoid compiler and linter exceptions in source file

My purpose is change trmplate from var serviceWorkerOption = ... to self.serviceWorkerOption = ... or even better self._serviceWorkerOption = ....
It helps to avoid compiler and linter exceptions (such as 'variable is not defined') for source file

sub directory filename

I'd like to add some filename like '/build/scope_a/sw.js'
But my application goes to donwload '/build' without other part of filename. Is there any case to implement filename with slash?
Thanks.

It seems that your are importing "serviceworker-webpack-plugin/lib/runtime" without using the plugin. Makes sure that your webpack configuration is correct.

When following the instructions I get the following error:
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.

This makes sense as serviceworker-webpack-plugin/lib/runtime just contains an error:

"use strict";

/* eslint-disable flowtype/require-valid-file-annotation */

throw new Error("serviceworker-webpack-plugin: It seems that your are importing\n > "serviceworker-webpack-plugin/lib/runtime" without using the plugin.\n Makes sure that your webpack configuration is correct.");

Why do we import a file that just contains an error? And what SHOULD we be doing?

Thanks.

registration.showNotification is not a function

I saw that the Html5 new Notification isn't supported on Android Chrome for web app notification (topic). The alternative is to use registration.showNotification('text.'), but the registration provided from runtime.register() doesn't have the showNotification function. Is this function actually available?

Based on your example:

class Main extends Component {
  componentDidMount() {
    if (
      'serviceWorker' in navigator &&
      (window.location.protocol === 'https:' || window.location.hostname === 'localhost')
    ) {
      const registration = runtime.register()
      registerEvents(registration, {
        onInstalled: () => {
             registration.showNotification('Hello.')
        }
      })
    }
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.