【问题标题】:How to import a script in Service Worker when using Webpack使用 Webpack 时如何在 Service Worker 中导入脚本
【发布时间】:2019-09-01 19:59:12
【问题描述】:

在 Service Worker 中,我尝试使用 importScripts 导入另一个帮助脚本,但我不断收到 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:5000/src/js/utility.js' failed to load.

我在 Service Worker 中有以下代码:

importScripts('../src/js/utility.js');

workbox.routing.registerRoute(/.*(?:jsonplaceholder\.typicode)\.com.*$/, function(args){
    console.log('Json placeholder being called');
    // Send request to the server.
    return fetch(args.event.request)
        .then(function(res){
            // Clone the response obtained from the server.
            var clonedRes = res.clone();
            // Clear data stored in the posts store.
            clearAllData('posts') // Function from helper file
                .then(function(){
                    return clonedRes.json()
                })
                .then(function(data){
                    for(var key in data){
                        // Write the updated data to the posts store.
                        writeData('posts', data[key]) // Function from helper file
                    }
                });

            return res;
        })
});

workbox.precaching.precacheAndRoute(self.__precacheManifest);

utility.js 我有以下代码:

import { openDB } from 'idb';

export function writeData(st, data){
    console.log(st, data);
}

export function clearAllData(st){
    console.log(st);
}

这些函数还没有做任何事情,但即使是这些占位符也不起作用!最终我希望能够使用idb npm 模块,这就是我在帮助程序中执行此操作的原因,因此我也可以从我的普通 Javascript 文件中使用它。
另外我正在使用 Webpack 构建我的文件,在另一个我不使用它的项目中,它工作正常,但是在这个项目中它只是在构建后找不到文件,所以我想 Webpack 可能是搞砸了。

提前致谢:)

【问题讨论】:

    标签: javascript webpack service-worker progressive-web-apps workbox-webpack-plugin


    【解决方案1】:

    如果您非常仔细地查看错误消息,您会发现问题所在:)

    您的 Service Worker 脚本尝试导入“/src/js/utility.js”,但它可用。如果您打开浏览器并转到该地址,您能看到该文件吗?我很确定你不能:)

    当您使用 webpack 构建应用程序时,它很可能会将您的所有文件放到一个名为“dist”的目录中。您的 Service Worker 能够导入这些文件。想一想:当你在某个地方部署应用程序时,只有 dist/ 中的文件会在服务器上,而不是 src/ 中的文件,对吧?因此,SW 脚本无法导入您希望它导入的文件。

    遗憾的是,我不是 webpack 专家,所以我不确定如何告诉 webpack 为您打包文件并将其包含在您的 Service Worker 脚本文件中:-/

    【讨论】:

      【解决方案2】:

      发现要导入脚本文件,我必须将它们原样复制到 dist 文件夹中,否则 Service Worker 将无法使用它们。 因此,我修改了vue.config.js 文件以包含以下内容(在module.exports 之后):

      chainWebpack: config => {
              config
                  .plugin('copy')
                  .tap(args => {
                      args[0].push({
                          from: 'project-location\\src\\js', 
                          to: 'project-location\\dist'});
                      return args;
                  })
          },
      

      这会将src/js中的文件复制到dist文件夹中,然后我们可以将它们导入到Service Worker文件中,文件顶部有这行:

      importScripts('utility.js');

      但是我还没有找到导入 npm 模块的方法,所以我不得不用另一个 idb.js 文件替换 idb 模块,该文件是在 utility.js 文件中导入的,具有类似的行代码:

      importScripts('idb.js');

      utility.jsidb.js 都位于src/js 下。

      所以不是一个完美的解决方案,但它有效。感谢pate 为我指明了正确的方向:)

      【讨论】:

      • 这似乎可行,但由于我有多个文件相互引用,此解决方案失败,仅适用于单个文件
      【解决方案3】:

      在这里,解决方法:

      1. 从您的服务器提供 javascript
      2. 用worker Api的self.importScripts()导入脚本,见https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts

      链接:

      【讨论】:

        【解决方案4】:

        我使用 CopyWebpackPlugin 来解决这个问题。它允许您复制文件并替换内容。因此,在复制后,我从文件中删除了所有“export”语句,这样我就只保留了一个版本。

        new CopyWebpackPlugin ([{
          from: 'src/js/mylist.js',
          to: '',
          transform(content) {
            return content.toString().replace(/export /g, '');
          },
        }])

        npm install -D copy-webpack-plugin 安装它

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-01
          • 1970-01-01
          • 2021-06-30
          • 2021-05-01
          • 2021-11-09
          • 1970-01-01
          • 2019-09-18
          • 2020-08-15
          相关资源
          最近更新 更多