如何使用Webpack 5加载服务工作人员?

70gysomp  于 2022-12-13  发布在  Webpack
关注(0)|答案(4)|浏览(212)

我正在使用Webpack 5,我希望有一个Service Worker,它可以拦截获取请求并在本地返回响应,而无需连接网络。我还希望能够在Service Worker中导入npm模块。我曾经使用一个名为 serviceworker-webpack-plugin 的库来实现此目的,但现在不再维护它了。Webpack文档推荐使用Workbox,但这似乎只是为了缓存ServiceWorker中的资产,据我所知。有人能告诉我在2020年用Webpack 5创建服务工人的正确方法是什么吗?

kdfy810k

kdfy810k1#

别把事情搞得太复杂。
你可以让一个软件工作只需2个步骤。创建一个软件并注册它。
创建一个.js文件(如sw.js)并在其中写入:

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.open('mysite-dynamic').then(function (cache) {
      return cache.match(event.request).then(function (response) {
        var fetchPromise = fetch(event.request).then(function (networkResponse) {
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        });
        return response || fetchPromise;
      });
    }),
  );
});

这就是过时而重新验证的方法
现在注册它。

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {
      // Registration was successful
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      // registration failed :(
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}
nom7f22z

nom7f22z2#

将服务工作器添加到webpack.config.js条目字段

entry: {
    'app': "./src/index.js",
    'service-worker': "./src/service-worker.ts",
},
output: {
    filename: "[name].js",
},

这将发出dist/app.jsdist/service-worker.js,并且可以在这两个文件中导入内容。
serviceworker-webpack-plugin还为serviceworker提供了一种方法,可以查看它应该缓存的所有bundle文件的列表,但该功能不能直接使用,需要制作一个webpack插件才能获得。

wn9m85ua

wn9m85ua3#

2022年答案

这是支持在webpack几乎开箱即用。
https://webpack.js.org/guides/progressive-web-application/
这将为您提供web pack为您处理的资源的基本缓存。
您可以获得更高级的:https://developer.chrome.com/docs/workbox/modules/workbox-webpack-plugin/
请注意,这是使用谷歌的Workbox。我已经在一个离线的第一个应用程序中使用了多年,它运行得非常好。

r8uurelv

r8uurelv4#

Webpack 5应该可以为您提供开箱即用的功能,与其他工作人员类似:
new URL for assets与new Worker/new SharedWorker/navigator.serviceWorker.register组合时,webpack将自动为web辅助进程创建新的入口点。
new Worker(new URL("./worker.js", import.meta.url)) .
选择此语法是为了允许在没有捆绑器的情况下运行代码。此语法在浏览器的本机ECMAScript模块中也可用。
(From https://webpack.js.org/blog/2020-10-10-webpack-5-release/#native-worker-support)
使用Webpack 4,我们的服务工作者代码如下所示:

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import downloadWorker from 'worker-plugin/loader!../workers/downloadHelper'

navigator.serviceWorker.register(downloadWorker).then( //...

在Webpack 5中,代码变为:

navigator.serviceWorker
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  .register(new URL('../workers/downloadHelper.ts', import.meta.url))
  .then( // ...

我们从webpack 5配置中删除了worker-plugin,v4的代码在import语句中使用了它。
关键是使用new URL()- webpack 5会将其解释为一个web worker,并为这个service worker创建一个块,并正确链接url。
我们必须添加eslint-disable-next-line@ts-ignore,因为navigator.serviceworker.register的接口需要一个字符串,而不是URL。看起来webpack正确地发送了一个字符串,但TypeScript似乎无法理解何时在webpack运行之前运行TypeScript。

相关问题