Как импортировать скрипт в Service Worker при использовании Webpack

В сервис-воркере я пытаюсь импортировать другой вспомогательный скрипт с помощью 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 может что-то напортачить.

Заранее спасибо :)


person Diatosta    schedule 11.04.2019    source источник


Ответы (4)


Если вы внимательно посмотрите на сообщение об ошибке, то увидите, в чем проблема :)

Ваш скрипт Service Worker пытается импортировать "/src/js/utility.js", но он НЕ доступен. Если вы откроете браузер и перейдете по этому адресу, сможете ли вы увидеть файл? Я почти уверен, что вы не можете :)

Когда вы создаете приложение с помощью веб-пакета, оно, скорее всего, помещает все ваши файлы в каталог с именем «dist». Ваш Service Worker может ТОЛЬКО импортировать эти файлы. Подумайте об этом: когда вы где-то развертываете приложение, на сервере будут только файлы из dist/, а не файлы из src/, верно? По этой причине сценарий SW не может импортировать файл, который вы хотите импортировать.

К сожалению, я не эксперт по веб-пакетам, поэтому я не уверен, как сказать веб-пакету связать файл для вас и включить его в ваш файл сценария Service Worker: -/

person pate    schedule 17.04.2019

Выяснил, что для импорта файлов сценариев я должен скопировать их в папку 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.js, и idb.js расположены под src/js.

Так что не идеальное решение, но оно работает. Спасибо pate за то, что указал мне правильное направление :)

person Diatosta    schedule 18.04.2019
comment
Кажется, это работает, но поскольку у меня есть несколько файлов, ссылающихся друг на друга, это решение не работает, работает только для одного файла. - person Vikas Saini; 15.01.2021

Здесь, обходной путь:

  1. обслуживать javascript с вашего сервера
  2. импортируйте скрипт с помощью self.importScripts() рабочего API, см. https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts.

Ссылки:

person Jimmy Obonyo Abor    schedule 01.02.2020

Я использую CopyWebpackPlugin для решения этой проблемы. Это позволяет копировать файлы и заменять содержимое. Поэтому после копирования я удаляю все операторы «экспорта» из своих файлов, что позволяет мне сохранить только одну версию.

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

npm install -D copy-webpack-plugin для его установки

person l1b3rty    schedule 20.12.2019