使用Webpack时如何在Service Worker中导入脚本

时间:2019-04-11 08:38:30

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

在服务工作者中,我尝试使用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可能是搞砸了。

预先感谢:)

4 个答案:

答案 0 :(得分:1)

解决方法:

  1. 从服务器中获取javascript
  2. 使用工作人员Api的self.importScripts()导入脚本,请参见https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts

链接:

答案 1 :(得分:0)

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

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

使用webpack构建应用程序时,很可能会将所有文件放在一个名为“ dist”的目录中。您的服务工作者只能 导入这些文件。想一想:将应用程序部署到某处时,只有dist /中的文件将在服务器上,而不是src /中的文件,对吗?因此,SW脚本无法导入您要导入的文件。

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

答案 2 :(得分:0)

发现要导入脚本文件,我必须将它们原样复制到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文件替换idb.js模块,该文件已导入utility.js中具有相似代码行的文件:

importScripts('idb.js');

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

所以不是一个完美的解决方案,但它可以工作。感谢pate为我指出正确的方向:)

答案 3 :(得分:0)

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

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

npm install -D复制-webpack-plugin进行安装