在service worker中使用import导入模块的正确姿势

418 阅读3分钟

我在service worker中添加了如下代码,引入我总备好的一个包时。直接导致我service worker安装失败任何错误也没有😭。思来想去才把这个问题解决了。特此将它记录下来,避免之后再犯类似的错误。

import '../node_modules/imforbossjob/dist/service/index.js';

在React或类似的现代前端单页面应用中,源代码通常位于src目录中,并使用类似于“../../”的相对路径来引用其他文件和模块。构建过程中,构建工具(如Webpack)会处理这些相对路径,并将所有的JavaScript、CSS和其他资源打包到public目录或者一个特定的构建输出目录(通常是distbuild)。这个过程中,构建工具会解析这些相对路径,并确保打包出来的文件中的引用路径是正确的。

然而,对于在public中的service_worker文件(也就是我们通常所说的service worker script),情况有所不同。service_worker脚本通常不会被包含在构建流程中,因为它直接处理与浏览器缓存相关的功能,而不是一个模块化的JavaScript应用程序的一部分。因此,它不会获得那种路径解析和模块打包的处理。

当你在service worker中尝试使用import加载一个模块时,你需要提供一个能够被浏览器直接访问的URL路径。这就是为什么你不能使用类似于“../../node_modules/...”这样的相对路径,因为service worker不是作为一个模块通过构建打包的,所以这样的路径解析对于浏览器来讲是没有意义的。

你需要做的是:

  1. 确保你要加载的文件在服务器上可以直接通过HTTP请求获取。通常来说,是放在public目录下面,或者是通过服务器配置映射到一个可以公开访问的URL路径上。
  2. service worker脚本中,使用完整的URL路径(如/node_modules/imforbossjob/dist/service/index.js)来引用这个模块。这样浏览器就能通过HTTP请求从服务端获取到这个文件。

如果你发现无法访问到对应的路径,证明你的服务器设置还不够,或者你的文件没有放在服务器设定的可以公开访问的位置。这就需要根据你所使用的服务器软件(例如Express.js、nginx等)调整配置,确保请求的文件可被正确服务。

我在service worker中引入的代码是这样的import../node_modules/imforbossjob/dist/service/index.js';因为本身就在public里面没有经过打包处理,所以最终浏览器访问的路径就变成了这样http://localhost:7008/node_modules/imforbossjob/dist/service/index.js你会发现根本就没办法访问,以至于service worker安装失败。

如何在service worker中使用import:type:module 即可。

 navigator.serviceWorker
    .register('/self_worker.js', { scope: '/', type: 'module' })
    .then(function (reg) {
      console.log('success', reg);
    })
    .catch(function (err) {
      console.log('fail', err);
    });