如何使用webpack注册服务工作者?

22

我正在使用webpack实现一个ReactJS Web应用程序,并希望开始实现服务工作者来处理网络调用,以便缓存文件。然而,我发现很难注册服务工作者的javascript文件。(需要说明的是,当涉及到React和webpack时,我都是初学者。)

如果我理解正确,webpack将每个javascript文件合并成一个bundle.js文件,这使得调用navigator.serviceWorker.register('./sw.js')...变得困难。我尝试了不同的方法,例如serviceworker-webpack-plugin,但都没有成功。如果我按照自述页面提供的步骤进行操作,就会出现错误消息,提示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.

这是我的webpack.config.js文件:

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'
    })
  ]
}

注意:我使用了create-react-app命令来开始。另外,我对服务工作者本身没有任何问题,我已经为另一个web应用程序实现了可工作的实现。我只是在注册它方面遇到了困难。
感谢您的帮助!

1
我发现将vanilla js service worker放入自己的文件中,并在webpack配置中添加它作为入口点很容易注册。我想深入了解一下React特定的service worker,如果触发了在线/离线事件,则监听并重新渲染给定组件。像你一样,我对React还很陌生,我想知道redux是否是这种行为的正确选择。不过,Redux仍然让我感到困惑! - Finbar Maginn
https://webpack.js.org/guides/progressive-web-application/ - Damien Golding
2个回答

27

为了消除错误,请更改

import ServiceWorkerWebpackPlugin from 'serviceworker-webpack-plugin';

为了

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

还要注意文档中有一个错别字:

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

请注意这里的单词Webpack拼写错误,应该是Webpack而不是Wepback

此外,文档中说明要使用以下代码在主JS线程上注册Service Worker:

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

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

然而,经过仔细检查,发现运行时目录是错误的。检查node_modules文件夹,

runtime location

看来runtime.jslib文件夹内。因此,为了解决这个问题,请更改
import runtime from 'serviceworker-webpack-plugin/runtime';

为了

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

我完成了这个步骤后,成功将 Service Worker 安装在我的开发环境中。

sw.js

虽然我还在学习 React 和 Webpack,但我还在尝试找到一种在 React 应用程序中正确使用 Service Worker 的方法。我也已经告知了插件作者文档中需要做出的更改。希望能帮助其他人!


我不知道为什么我的sw.js文件中有webpack引导代码。 - hannad rehman
@Nicholas Lie,我该如何在这里使用默认的serviceWorker.js?当我使用上述插件时,它会出现窗口对象错误。 - Sabbir Ahmed

-7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接