Вопрос или проблема
Я работаю над расширением для браузера. В Chrome я могу сделать это:
manifest.json:
"background": {
"service_worker": "scripts/vh_service_worker.js",
},
и в моем сервис-воркере я могу использовать importScript("somefile.js")
без проблем.
В Firefox background.service_worker
не реализован для манифеста v3.
Попытка #1:
Я загружаю сервис-воркер как фоновый скрипт:
manifest.json:
"background": {
"scripts": ["scripts/vh_service_worker.js"]
},
Это в целом работает хорошо, но, к сожалению, кажется, что он не выполняется в WorkerGlobalScope
, поэтому функция importScripts()
недоступна.
Попытка #2:
Я попытался использовать фоновый скрипт для регистрации сервис-воркера вручную:
manifest.json:
"background": {
"scripts": ["scripts/vh_service_worker_loader.js"]
},
vh_service_worker_loader.js:
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("scripts/vh_service_worker.js")
.then((registration) => {
console.log("Сервис-воркер зарегистрирован с областью:", registration.scope);
})
.catch((error) => {
console.error("Ошибка регистрации сервис-воркера:", error);
});
}
Но, к сожалению, нет доступной записи navigator.serviceWorker
, поэтому условие if всегда возвращает false.
Так что мой вопрос:
Как я могу использовать importScripts()
в Firefox для расширения, использующего манифест V3?
Ответ или решение
К сожалению, использование importScripts()
в фоне (background script) веб-расширений на основе манифеста версии 3 (Manifest V3) в Firefox действительно ограничено, так как функция importScripts()
доступна только в контексте веб-воркеров. В этой связи существуют несколько обходных путей, чтобы решить эту проблему.
Решение 1: Использование import
вместо importScripts()
С 2023 года современный JavaScript поддерживает модули ES. Если вы можете переработать ваши скрипты, попробуйте имплементировать динамическую загрузку модулей с использованием import
. Для этого вам нужно будет адаптировать ваши JS-файлы в соответствии с требованиями ES6.
Ваш файл vh_service_worker.js
может выглядеть следующим образом:
// vh_service_worker.js
import { someFunction } from './somefile.js';
// Используйте someFunction и другие экспортированные элементы
Таким образом, ваша структура manifest.json
будет несколько похожа на следующую:
"background": {
"service_worker": "scripts/vh_service_worker.js"
},
Решение 2: Использование self.importScripts()
Если вы все же хотите использовать importScripts()
и ваш сценарий должен оставаться в стиле совместимости с CommonJS, вам нужно убедиться, что у вас действительно загружен сервис-воркер. В background
сценариях для Manifest V3 вы не можете регистрировать Service Workers через navigator.serviceWorker
, как это относится к контексту веб-страницы, но вы можете использовать фреймворки или библиотеки для повышения совместимости.
Решение 3: Использование промисов
Если ваши скрипты требуют асинхронной загрузки, рассмотрите возможность создания специальной функции, которая будет загружать зависимости с использованием fetch
и eval
. Хотя это менее предпочтительно, оно все же позволяет параллельно загружать необходимые модули.
Пример функции:
async function loadScript(url) {
const response = await fetch(url);
const text = await response.text();
eval(text);
}
// Пример использования
loadScript('scripts/somefile.js').then(() => {
// Теперь вы можете использовать функции из somefile.js
});
Заключение
К сожалению, importScripts()
не доступен в background
скриптах при использовании Manifest V3 в Firefox. Рекомендую вам использовать ES6 модули и переосмыслить архитектуру ваших скриптов, чтобы они использовали стандартные возможности JavaScript, такие как import
и export
. Это позволит вам улучшить совместимость и упростить работу с модульной системой.