<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Модули в Service Workers: импорт JS с type=module для офлайн-приложений]]></title><description><![CDATA[<p dir="auto">Service Workers позволяют кешировать ресурсы и работать офлайн, но их код часто разрастается. Импорт модулей с type=“module” решает эту проблему - делит логику на файлы, упрощает поддержку и ускоряет разработку. Это особенно полезно для PWA, где офлайн-доступ критичен.</p>
<p dir="auto">Подход с ES-модулями заменяет старый importScripts(), делая код чище и современнее. Вы сможете импортировать утилиты, конфиги или даже общие функции между worker’ом и главной страницей. В итоге офлайн-приложения станут надежнее, а разработка - быстрее.</p>
<h2>Что такое модули в Service Workers</h2>
<p dir="auto">Service Worker - это скрипт, который перехватывает сетевые запросы и управляет кешем. Раньше для загрузки дополнительного JS использовался importScripts(), но он синхронный и неудобный для больших проектов. С ES-модулями вы пишете import … from ‘…’ прямо в worker’е, браузер сам разберет зависимости.</p>
<p dir="auto">Это работает только со <strong>статическими импортами</strong> - динамические import() пока не поддерживаются в SW. Браузер кеширует все модули во время установки worker’а, гарантируя офлайн-доступ. Представьте: один config.js для кеша используется и в SW, и на странице - никаких дубликатов.</p>
<ul>
<li><strong>Статический импорт</strong>: <code>import { cacheName } from './config.js';</code> - простой и надежный.</li>
<li><strong>Автоматический кеш</strong>: Все зависимости загружаются и сохраняются при install.</li>
<li><strong>Совместимость</strong>: Работает в Chrome, Firefox, Safari с 2020-х годов.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Сравнение подходов</th>
<th>importScripts()</th>
<th>ES modules</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Синхронность</strong></td>
<td>Синхронный</td>
<td>Асинхронный</td>
</tr>
<tr>
<td><strong>Зависимости</strong></td>
<td>Ручное управление</td>
<td>Автоматическое</td>
</tr>
<tr>
<td><strong>Tree-shaking</strong></td>
<td>Нет</td>
<td>Да</td>
</tr>
<tr>
<td><strong>Офлайн</strong></td>
<td>Частичный</td>
<td>Полный</td>
</tr>
</tbody>
</table>
<p dir="auto"><em>Важно</em>: Укажите type: ‘module’ при регистрации SW, иначе браузер не поймет импорты.</p>
<h2>Как настроить импорт модулей</h2>
<p dir="auto">Регистрация Service Worker с модулями начинается с navigator.serviceWorker.register(‘sw.js’, { type: ‘module’ }). Без этого параметра импорт не сработает - браузер воспримет файл как классический скрипт. В самом sw.js добавьте import для нужных модулей, например, конфига или утилит для fetch.</p>
<p dir="auto">Допустим, у вас есть utils.js с функцией для кеширования изображений. Импортируйте ее в SW и используйте в обработчике fetch. Браузер загрузит utils.js автоматически, проверит MIME-тип и закеширует. Если модуль уже на странице, его можно переиспользовать - экономия трафика.</p>
<ol>
<li>Создайте config.js: <code>export const cacheName = 'v2-offline';</code>.</li>
<li>В index.html: <code>&lt;script type="module"&gt; import {cacheName} from './config.js'; ... navigator.serviceWorker.register('sw.js', {type: 'module'}); &lt;/script&gt;</code>.</li>
<li>В sw.js: <code>import {cacheName} from './config.js'; self.addEventListener('install', ...);</code>.</li>
</ol>
<pre><code class="language-javascript">// sw.js
self.addEventListener('fetch', event =&gt; {
  event.respondWith(
    caches.match(event.request).then(resp =&gt; resp || fetch(event.request))
  );
});
</code></pre>
<p dir="auto"><strong>Плюс</strong>: Модули изолированы, нет глобальных переменных. <em>Нюанс</em>: Все импорты должны быть относительными путями.</p>
<h2>Офлайн-приложения на модулях</h2>
<p dir="auto">В офлайн-режиме SW с модулями показывает силу: все зависимости закешированы статически. При установке worker’а браузер загружает граф зависимостей и сохраняет файлы в Cache Storage. Даже если сеть пропала, fetch-обработчик вернет ресурсы из кеша.</p>
<p dir="auto">Пример: PWA для новостного сайта. Модуль newsFetcher.js импортируется в SW и странице. Офлайн пользователь видит кешированные статьи, обновления приходят при подключении. Это лучше, чем старый подход с динамическими скриптами, которые могли не загрузиться.</p>
<ul>
<li>Кеш стратегия: <code>caches.open(cacheName).then(cache =&gt; cache.addAll(['/js/app.js', '/css/style.css']));</code>.</li>
<li>Перехват: В fetch проверяйте URL и возвращайте из кеша.</li>
<li>Обновление: При активации удаляйте старый кеш.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Стратегия кеша</th>
<th>Описание</th>
<th>Пример</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Cache first</strong></td>
<td>Кеш, потом сеть</td>
<td>Изображения</td>
</tr>
<tr>
<td><strong>Network first</strong></td>
<td>Сеть, потом кеш</td>
<td>API</td>
</tr>
<tr>
<td><strong>Stale-while-revalidate</strong></td>
<td>Кеш + фоновая сеть</td>
<td>Статьи</td>
</tr>
</tbody>
</table>
<p dir="auto"><em>Совет</em>: Тестируйте в Chrome DevTools с отключенной сетью.</p>
<h2>Практические примеры кода</h2>
<p dir="auto">Начнем с базового SW. В config.js экспортируем имя кеша и список ресурсов. Импортируем в worker и используем для install. Страница регистрирует SW с type=‘module’ и тоже импортирует config - синхронизация без копипаста.</p>
<p dir="auto">В реальном проекте добавьте модуль для обработки API. Функция getDataFromCache() проверяет кеш, fallback на сеть. В fetch SW вызывает ее по URL. Офлайн - данные из кеша, онлайн - свежие с обновлением.</p>
<ol>
<li>utils.js: <code>export async function cacheResponse(request, response) { ... }</code>.</li>
<li>sw.js: <code>import {cacheResponse} from './utils.js';</code>.</li>
<li>Обработчик: <code>event.respondWith(cacheResponse(event.request, fetch(event.request)));</code>.</li>
</ol>
<p dir="auto"><strong>Ключ</strong>: Используйте response.clone() для одновременного кеширования и отдачи.</p>
<h2>Масштабирование с Shared Modules</h2>
<p dir="auto">Когда проект растет, модули позволяют делить код между SW и клиентом. Один requests.js с fetch-логикой импортируется везде. В SW - для кеша ответов, на странице - для UI. Это снижает размер бандла и упрощает рефакторинг.</p>
<p dir="auto">Но учтите лимиты: SW не имеет DOM, модули должны быть чистыми функциями. Для больших приложений бандлите через Vite или Webpack в IIFE для старых браузеров. Современные браузеры тянут нативные модули отлично.</p>
<ul>
<li><strong>Общий модуль</strong>: Экспорт функций без window/global.</li>
<li><strong>Бандлинг</strong>: <code>vite build --ssr sw.js</code> для production.</li>
<li><strong>TypeScript</strong>: Компилируйте в ES modules с “module”: “ESNext”.</li>
</ul>
<h2>Готовность к production</h2>
<p dir="auto">В продакшене настройте versioning кеша и skipWaiting() для быстрого обновления SW. Модули помогут: просто поменяйте config.js, worker обновится. Тестируйте на реальных устройствах - офлайн, медленный 3G.</p>
<p dir="auto">Остается пространство для экспериментов: интеграция с Worklets или динамические импорты в будущем. Подумать стоит над стратегиями предзагрузки ML-моделей в SW для умных офлайн-приложений.</p>
]]></description><link>https://forum.exlends.ru/topic/1321/moduli-v-service-workers-import-js-s-type-module-dlya-oflajn-prilozhenij</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 03:26:31 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/1321.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 07 Mar 2026 13:34:48 GMT</pubDate><ttl>60</ttl></channel></rss>