Большое спасибо Маттиасу Буэленсу , который указал мне правильное направление.
Вот рабочий пример .
Структура проекта:
dist
src
generic-tsconfig.json
main
- (машинописные файлы)
tsconfig.json
dedicated-worker
- (машинописные файлы)
tsconfig.json
service-worker
- (машинописные файлы)
tsconfig.json
src/generic-tsconfig.json
Содержит конфигурацию, общую для каждого проекта:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"moduleResolution": "node",
"rootDir": ".",
"outDir": "../dist",
"composite": true,
"declarationMap": true,
"sourceMap": true
}
}
Я сознательно избегал называть это tsconfig.json
, так как это не сам проект.Адаптируйте вышеупомянутое к вашим потребностям.Вот важные части:
outDir
- Это место, куда будут перемещаться скрипты, объявления и исходные карты. rootDir
- Установив для этого значение src
каталог, каждый из подпроектов (main
, dedicated-worker
, service-worker
) будет отображаться как подкаталоги в outDir
, в противном случае они будут пытаться использовать один и тот же каталог и перезаписывать друг друга. composite
- это необходимо для TypeScript для сохранения ссылок между проектами.
Не включайте references
в этот файл.Они будут проигнорированы по какой-то недокументированной причине (вот где я застрял).
src/main/tsconfig.json
Это конфигурация для проекта «основного потока», как, например, JavaScriptкоторый будет иметь доступ к документу.
{
"extends": "../generic-tsconfig.json",
"compilerOptions": {
"lib": ["esnext", "dom"],
},
"references": [
{"path": "../dedicated-worker"},
{"path": "../service-worker"}
]
}
extends
- Это указывает на нашу общую конфигурацию выше. compilerOptions.lib
- Библиотеки, используемые этим проектом.В этом случае JS и DOM. references
- Поскольку это основной проект (тот, который мы создаем), он должен ссылаться на все другие подпроекты, чтобы гарантировать, что они также построены.
src/dedicated-worker/tsconfig.json
Это конфигурация для выделенного работника (тип, который вы создаете с помощью new Worker()
).
{
"extends": "../generic-tsconfig.json",
"compilerOptions": {
"lib": ["esnext", "webworker"],
}
}
Вам не нужно ссылаться надругие подпроекты здесь, если вы не импортируете вещи из них (например, типы).
Использование выделенных рабочих типов
TypeScript не делает различий между различными рабочими контекстами, несмотря на то, что они имеют разные глобальные значения.Таким образом, все становится немного беспорядочно:
postMessage('foo');
Это работает, поскольку типы TypeScript для «веб-рабочих» создают глобальные переменные для всех выделенных рабочих глобальных глобальных переменных.Однако:
self.postMessage('foo');
… это не работает, так как TypeScript дает self
несуществующий тип, своего рода абстрактный глобальный рабочий.
Чтобы это исправить, включите это в свой источник:
declare var self: DedicatedWorkerGlobalScope;
export {};
Это устанавливает self
на правильный тип.
Бит declare var
не работает, если файл не является модулем, а фиктивный экспорт заставляет TypeScript его обрабатыватькак модуль.Это означает, что вы объявляете self
в области видимости модуля, которой в данный момент не существует.В противном случае вы пытаетесь объявить его на глобальном уровне, где он действительно уже существует.
src/service-worker/tsconfig.json
То же, что и выше.
{
"extends": "../generic-tsconfig.json",
"compilerOptions": {
"lib": ["esnext", "webworker"],
}
}
Использование типов рабочих служб
Как и выше, типы "веб-работников" TypeScript создают глобальные переменные для всех выделенных глобальных рабочих.Но это не выделенный работник, поэтому некоторые типы являются неправильными:
postMessage('yo');
TypeScript не жалуется на вышеперечисленное, но он потерпит неудачу во время выполнения, так как postMessage
не включенглобальный сервисный работник.
К сожалению, вы ничего не можете сделать, чтобы исправить реальный глобал, но вы все равно можете исправить self
:
declare var self: ServiceWorkerGlobalScope;
export {};
Теперь вам нужно убедиться, что каждый глобал особенныйк сервисным работникам обращаются через self
.
addEventListener('fetch', (event) => {
// This is a type error, as the global addEventListener
// doesn't know anything about the 'fetch' event.
// Therefore it doesn't know about event.request.
console.log(event.request);
});
self.addEventListener('fetch', (event) => {
// This works fine.
console.log(event.request);
});
Те же проблемы и обходные пути существуют для других типов работников, таких как рабочие места и общие рабочие.
Building
tsc --build src/main
И это все!