Модули в Service Workers: импорт JS с type=module для офлайн-приложений
-
Service Workers позволяют кешировать ресурсы и работать офлайн, но их код часто разрастается. Импорт модулей с type=“module” решает эту проблему - делит логику на файлы, упрощает поддержку и ускоряет разработку. Это особенно полезно для PWA, где офлайн-доступ критичен.
Подход с ES-модулями заменяет старый importScripts(), делая код чище и современнее. Вы сможете импортировать утилиты, конфиги или даже общие функции между worker’ом и главной страницей. В итоге офлайн-приложения станут надежнее, а разработка - быстрее.
Что такое модули в Service Workers
Service Worker - это скрипт, который перехватывает сетевые запросы и управляет кешем. Раньше для загрузки дополнительного JS использовался importScripts(), но он синхронный и неудобный для больших проектов. С ES-модулями вы пишете import … from ‘…’ прямо в worker’е, браузер сам разберет зависимости.
Это работает только со статическими импортами - динамические import() пока не поддерживаются в SW. Браузер кеширует все модули во время установки worker’а, гарантируя офлайн-доступ. Представьте: один config.js для кеша используется и в SW, и на странице - никаких дубликатов.
- Статический импорт:
import { cacheName } from './config.js';- простой и надежный. - Автоматический кеш: Все зависимости загружаются и сохраняются при install.
- Совместимость: Работает в Chrome, Firefox, Safari с 2020-х годов.
Сравнение подходов importScripts() ES modules Синхронность Синхронный Асинхронный Зависимости Ручное управление Автоматическое Tree-shaking Нет Да Офлайн Частичный Полный Важно: Укажите type: ‘module’ при регистрации SW, иначе браузер не поймет импорты.
Как настроить импорт модулей
Регистрация Service Worker с модулями начинается с navigator.serviceWorker.register(‘sw.js’, { type: ‘module’ }). Без этого параметра импорт не сработает - браузер воспримет файл как классический скрипт. В самом sw.js добавьте import для нужных модулей, например, конфига или утилит для fetch.
Допустим, у вас есть utils.js с функцией для кеширования изображений. Импортируйте ее в SW и используйте в обработчике fetch. Браузер загрузит utils.js автоматически, проверит MIME-тип и закеширует. Если модуль уже на странице, его можно переиспользовать - экономия трафика.
- Создайте config.js:
export const cacheName = 'v2-offline';. - В index.html:
<script type="module"> import {cacheName} from './config.js'; ... navigator.serviceWorker.register('sw.js', {type: 'module'}); </script>. - В sw.js:
import {cacheName} from './config.js'; self.addEventListener('install', ...);.
// sw.js self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(resp => resp || fetch(event.request)) ); });Плюс: Модули изолированы, нет глобальных переменных. Нюанс: Все импорты должны быть относительными путями.
Офлайн-приложения на модулях
В офлайн-режиме SW с модулями показывает силу: все зависимости закешированы статически. При установке worker’а браузер загружает граф зависимостей и сохраняет файлы в Cache Storage. Даже если сеть пропала, fetch-обработчик вернет ресурсы из кеша.
Пример: PWA для новостного сайта. Модуль newsFetcher.js импортируется в SW и странице. Офлайн пользователь видит кешированные статьи, обновления приходят при подключении. Это лучше, чем старый подход с динамическими скриптами, которые могли не загрузиться.
- Кеш стратегия:
caches.open(cacheName).then(cache => cache.addAll(['/js/app.js', '/css/style.css']));. - Перехват: В fetch проверяйте URL и возвращайте из кеша.
- Обновление: При активации удаляйте старый кеш.
Стратегия кеша Описание Пример Cache first Кеш, потом сеть Изображения Network first Сеть, потом кеш API Stale-while-revalidate Кеш + фоновая сеть Статьи Совет: Тестируйте в Chrome DevTools с отключенной сетью.
Практические примеры кода
Начнем с базового SW. В config.js экспортируем имя кеша и список ресурсов. Импортируем в worker и используем для install. Страница регистрирует SW с type=‘module’ и тоже импортирует config - синхронизация без копипаста.
В реальном проекте добавьте модуль для обработки API. Функция getDataFromCache() проверяет кеш, fallback на сеть. В fetch SW вызывает ее по URL. Офлайн - данные из кеша, онлайн - свежие с обновлением.
- utils.js:
export async function cacheResponse(request, response) { ... }. - sw.js:
import {cacheResponse} from './utils.js';. - Обработчик:
event.respondWith(cacheResponse(event.request, fetch(event.request)));.
Ключ: Используйте response.clone() для одновременного кеширования и отдачи.
Масштабирование с Shared Modules
Когда проект растет, модули позволяют делить код между SW и клиентом. Один requests.js с fetch-логикой импортируется везде. В SW - для кеша ответов, на странице - для UI. Это снижает размер бандла и упрощает рефакторинг.
Но учтите лимиты: SW не имеет DOM, модули должны быть чистыми функциями. Для больших приложений бандлите через Vite или Webpack в IIFE для старых браузеров. Современные браузеры тянут нативные модули отлично.
- Общий модуль: Экспорт функций без window/global.
- Бандлинг:
vite build --ssr sw.jsдля production. - TypeScript: Компилируйте в ES modules с “module”: “ESNext”.
Готовность к production
В продакшене настройте versioning кеша и skipWaiting() для быстрого обновления SW. Модули помогут: просто поменяйте config.js, worker обновится. Тестируйте на реальных устройствах - офлайн, медленный 3G.
Остается пространство для экспериментов: интеграция с Worklets или динамические импорты в будущем. Подумать стоит над стратегиями предзагрузки ML-моделей в SW для умных офлайн-приложений.
- Статический импорт:
Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.
Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.
С вашими комментариями этот пост мог бы стать ещё лучше 💗
Зарегистрироваться Войти© 2024 - 2026 ExLends, Inc. Все права защищены.