繁体   English   中英

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

[英]How to load a service worker using Webpack 5?

我正在使用 Webpack 5,我希望有一个 Service Worker 可以在不访问 .network 的情况下拦截获取请求并在本地返回响应。 我还希望能够在 Service Worker 中导入 npm 模块。 为此,我曾经使用一个名为serviceworker-webpack-plugin的库,但它不再维护,(并且在我使用它时会抛出错误)。 Webpack 文档推荐使用 Workbox,但据我所知,这似乎只是为了在 Service Worker 中缓存资产。 有人能告诉我在 2020 年使用 Webpack 5 创建 Service Worker 的正确方法是什么吗?

将 service worker 添加到您的 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 提供了一种查看它应该缓存的所有捆绑文件列表的方法,但该功能不能直接使用,需要制作 webpack 插件才能获取。

不要过于复杂。

您只需 2 个步骤即可使 sw 工作。 创建一个软件并注册它。

创建一个 .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;
      });
    }),
  );
});

这就是stale-while-revalidate方法

现在注册它。

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);
    });
  });
}

2022答案

这在 webpack 中几乎是开箱即用的。

https://webpack.js.org/guides/progressive-web-application/

这将为您提供 webpack 正在为您处理的资产的基本缓存。

您可以获得更高级的: https ://developer.chrome.com/docs/workbox/modules/workbox-webpack-plugin/

请注意,这是使用 google 的 Workbox。 我已经在离线第一个应用程序中使用了多年,并且效果很好。

Webpack 5 应该为您开箱即用,类似于其他工作人员:

当将资产的new URLnew Worker / new SharedWorker/navigator.serviceWorker.register webpack 组合时,将自动为 web worker 创建一个新的入口点。

new Worker(new URL("./worker.js", import.meta.url))

选择的语法也允许在没有捆绑器的情况下运行代码。 此语法也可用于浏览器的原生 ECMAScript 模块。

(来自https://webpack.js.org/blog/2020-10-10-webpack-5-release/#native-worker-support

对于 webpack 4,我们的 Service Worker 代码如下所示:

// 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 似乎无法理解 TypeScript 在 webpack 运行之前运行的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM