Как я могу использовать importScripts() в Service Worker при использовании Webpack?

#javascript #webpack #service-worker #progressive-web-apps #workbox-webpack-plugin

#javascript #webpack #service-worker #progressive-веб-приложения #workbox-webpack-плагин

Вопрос:

В 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 может что-то испортить.

Заранее спасибо 🙂

Ответ №1:

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

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

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

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

Комментарии:

1. Если это так, вы получите другую ошибку с указанием кода ответа (404). Если вы не видите такого сообщения, это означает, что скрипт доступен, но проблема где-то в другом месте

Ответ №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 модуль другим idb.js файлом, который импортируется в utility.js файл с аналогичной строкой кода:

importScripts('idb.js');

Оба utility.js и idb.js находятся под src/js .

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

Комментарии:

1. Кажется, это работает, но поскольку у меня есть несколько файлов, ссылающихся друг на друга, это решение не работает, работает только для одного файла

Ответ №3:

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

  1. обслуживайте javascript со своего сервера
  2. импортируйте скрипт с self.importScripts() помощью workers Api, см. 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 для его установки