TGViewer
<divelopers> <divelopers> @alexnozer_dev · 1.18K subscribers
Post #253 896
Импорт (почти) чего угодно в браузере

Стандарт ES2015 (ES6) принёс в JS систему модулей — ESM. Те самые import ... from ..., которые стали неотъемлемой частью разработки на JS. У ESM в браузере есть ограничения:

- Путь к модулю должен быть относительным (начинаться с /, ./, ../) или абсолютным;
- Путь к модулю должен заканчиваться именем файла с расширением .js;
- Импортировать можно только JS-модули.

ESM не стоит на месте. Недавно в стандарт добавили JSON и CSS модули. В будущем ожидается добавление HTML модулей. Также появилась возможность указывать псевдонимы для путей к модулям с помощью Import maps.

Сегодня многие проекты используют системы сборки для упаковки кода. В кодовых базах таких проектов будет нечто похожее на ESM. Но это не настоящий ESM, а специальный синтаксис инструкций для сборщиков:

// 'react' — невалидный путь без псевдонима
import React from 'react';

// импорт .css возможен только через with
import styles from './styles.css';

// импорт изображений не поддерживается
import imgUrl from './img.png';

// недопустимый символ ~ в пути
import { someUtil } from '~/src/utils.js';

// glob patterns не поддерживаются
import * as pages from './pages/*/*.js';

// невалидный путь к модулю
import workletUrl from 'worklet:./worklet.js';

// параметр url игнорируется
import assetAsURL from './asset.js?url';


Это удобно, но не работает в браузере. Поэтому сборщики выполняют преобразования. Как и во что превращаются импорты под капотом — зависит от сборщика и настроек. Тем не менее, нестандартные импорты можно заставить работать в браузере.

Импорт в браузере — это HTTP-запрос к ресурсу. Запрос можно перехватить с помощью Service Worker. Браузер ожидает валидный JS-модуль, значит Service Worker должен его вернуть в ответ на перехваченный запрос импорта.

Для текстовых форматов (HTML, CSS) проще всего создать модуль, который экспортирует содержимое запрашиваемых файлов в виде строки. Дополнительно HTML можно преобразовать в объект DocumentFragment, а CSS в объект CSSStyleSheet.

// sw.js
async function createHTMLModule(html) {
return `
const template = document.createElement('template');
template.innerHTML = \`${html}\`;
export default template.content;
`;
}

async function createCSSModule(css) {
return `
const styles = new CSSStyleSheet();
styles.replaceSync(\`${css}\`);
export default styles;
`;
}

self.addEventListener('fetch', (event) => {
const { destination, url } = event.request;

if (destination === 'script') {
const response = await self.fetch(url);
const text = await response.text();
let module = text;

if (url.endsWith('.html')) {
module = createHTMLModule(text);
} else if (url.endsWith('.css')) {
module = createCSSModule(text);
}

event.respondWith(
new Response(
module,
{
headers: {
'Content-Type': 'text/javascript'
}
}
)
);
}
});

// main.js
import template from './template.html';
import styles from './styles.css';

console.log(template);
// DocumentFragment

console.log(styles);
// CSSStyleSheet


Само собой, Service Worker должен быть подключен к странице и зарегистрирован до того, как будут обрабатываться нестандартные импорты. Таким образом можно импортировать, в принципе, любые ресурсы, предоставляя их браузеру в виде JS-модулей.

#js
  • 🔥 17
  • ❤ 5
  • 👍 5
More from @alexnozer_dev
  1. Sep 23, 2026Images Preview На некоторых сайтах, где надо показывать изображения в высоком качестве, дл…
  2. Sep 21, 2026Реализация пользовательских атрибутов Под конец прошлого года я рассказывал об API пользов…
  3. Sep 14, 2026Подклассы Event вместо CustomEvent Многие библиотеки предоставляют систему событий в качес…
  4. Sep 11, 2026Эволюция стилей в темах Shopify Адам Ватан на днях поделился новостью, что Shopify выкупил…
  5. Sep 9, 2026Persistent Widgets Многие сайты не должны быть SPA. Но иногда эта архитектура продиктована…
  6. Sep 7, 2026Processing Instructions и маркеры В DOM всё представлено в виде узлов (Node) разных типов.…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →