最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I use importScripts() in a Service Worker when using Webpack? - Stack Overflow

programmeradmin2浏览0评论

In a Service Worker, I'm trying to import another helper script using importScripts, however I keep getting a Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:5000/src/js/utility.js' failed to load.

I have the following code in the Service Worker:

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

workbox.routing.registerRoute(/.*(?:jsonplaceholder\.typicode)\.*$/, 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);

And in utility.js I have the following code:

import { openDB } from 'idb';

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

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

The functions don't do anything yet, but even these placeholder ones don't work! Eventually I'd like to be able to use the idb npm module, so that's why I'm doing this in a helper, so I can also use it from my normal Javascript file.
Also I'm using Webpack to build my files, and in another project where I don't use it, it works fine, however in this one it just doesn't find the file after building, so I'm thinking Webpack may be screwing something up.

Thanks in advance :)

In a Service Worker, I'm trying to import another helper script using importScripts, however I keep getting a Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:5000/src/js/utility.js' failed to load.

I have the following code in the 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);

And in utility.js I have the following code:

import { openDB } from 'idb';

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

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

The functions don't do anything yet, but even these placeholder ones don't work! Eventually I'd like to be able to use the idb npm module, so that's why I'm doing this in a helper, so I can also use it from my normal Javascript file.
Also I'm using Webpack to build my files, and in another project where I don't use it, it works fine, however in this one it just doesn't find the file after building, so I'm thinking Webpack may be screwing something up.

Thanks in advance :)

Share Improve this question edited Jan 25, 2023 at 17:18 mikemaccana 123k110 gold badges427 silver badges531 bronze badges asked Apr 11, 2019 at 8:38 DiatostaDiatosta 1211 gold badge1 silver badge5 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 6

If you look at the error message very carefully, you see what the problem is :)

Your Service Worker script tries to import "/src/js/utility.js" but it is NOT available. If you open your browser and go to that address, can you see the file? I'm fairly sure you cannot :)

When you build the application with webpack it most likely puts all your files to a directory called "dist". Your Service Worker is ONLY able to import those files. Think about it: when you deploy the application somewhere, only the files in dist/ will be on the server, not the files in src/, right? For this reason the SW script is not able to import the file you want it to import.

Sadly I'm not a webpack expert so I'm not sure how to tell webpack to bundle the file for you and include it in your Service Worker script file :-/

Found out that to import script files, I have to copy them to the dist folder as they are, otherwise they won't be usable by the Service Worker. As such, I modified the vue.config.js file to include the following (after module.exports):

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

This will copy the files in src/js to the dist folder, and then we can import them in the Service Worker file with this line at the top of the file:

importScripts('utility.js');

I haven't however been able to find a way to import npm modules, so I had to replace the idb module with another idb.js file, that is imported in the utility.js file with a similar line of code:

importScripts('idb.js');

Both utility.js and idb.js are located under src/js.

So not a perfect solution, but it works. Thanks to pate for pointing me in the right direction :)

Here , workaround :

  1. serve the javascript from your server
  2. import the script with self.importScripts() of the workers Api , see https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts.

Links:

  • https://developers.google.com/web/updates/2019/09/fresher-sw
  • https://web.dev/module-workers/

I use the CopyWebpackPlugin to solve this issue. It lets you copy files and replace content. So after copying I remove all the export statements from my files, which allows me to keep only one version.

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

To install it: npm install -D copy-webpack-plugin

发布评论

评论列表(0)

  1. 暂无评论