Не работает import в web workers
Создал экземпляр класса Worker, в котором импортируется файл, но при запуске появляется ошибка в консоли "import declarations may only appear at top level of a module"
Код файла вызова воркера:
const worker = new Worker('./js/workers/calculateRequestData.js', {
type: 'module',
});
worker.postMessage({ data: '1' });
worker.addEventListener('message', (event) => {
console.log(event.data);
});
worker.addEventListener('error', (error) => {
console.error(error.message);
});
Код файла calculateRequestData.js
import template from '../Template/template.js';
onmessage = function (e) {
console.log(e.data);
postMessage(e.data);
};
В нетворках файлы приходят со статусом 304 (если это поможет)
Пробовал делать:
import template from '../Template/template.js' assert { type: 'module' }self.template = require('../js/Template/template.js// Ошибка: require не найден (или не работает, что-то такое)self.importScripts('../js/Template/template.js')// Ошибка та же что и в предыдущем пункте, только про importScripts.
Все это тоже не работает
Ответы (1 шт):
Ошибка заключалась в использовании "стандартного import ... from '...'"
Файл воркера превращается в один файл со скриптом, где не должно быть экспортов и импортов(в привычном для модулей виде). Для того чтобы импортировать файл, или несколько файлов, в воркер нужно использовать importScripts() (можно не использовать ключевое слово self).
importScripts() "разворачивает" импортируемый файл в файле воркера.
Во vue cli файлы воркера и все его импортируемые файлы должны храниться не в src директории, а в public. Это связанно с тем что они не компилируются в общий бандл, а делается запрос к конкретному файлу.
Пример правильного кода:
Файл с вызовом воркера:
const worker = new Worker('./js/workers/calculateRequestData.js');
worker.postMessage({...});
worker.addEventListener('message', (event) =>
console.error(event.data); // обрабатываем сообщения
worker.terminate(); // не забываем удалять воркер
});
worker.addEventListener('error', (error) => {
console.error(error.message); // обрабатываем ошибки
worker.terminate(); // не забываем удалять воркер
});
Файл calculateRequestData.js
self.importScripts('../Template/template.js');
onmessage = function (e) {
template.calculate(...) // работаем с импортированными данными
};
Также столкнулся с проблемой, когда продакшн сборка не работала из-за не правильного mime-type ('application/octet-stream') файлов воркера и импортируемого скрипта. Это связанно с тем что у нас сервер по умолчанию отдавал файлы с таким mime-type, при этом браузер по умолчанию вызывает модальное окно "Сохранить как". Это лечится указанием в конфигурационном файле для mime типов добавлением строчки 'application/octet-stream' Решение было найдено здесь - https://stackoverflow.com/questions/8744376/application-octet-stream-mime-type-issue-with-codeigniter
Пример:
'js' => [
'application/x-javascript',
'text/plain',
'application/octet-stream',
],