[JavaScript] Контролируем JavaScript импорты с помощью Import maps
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Привет. С выходом Chrome 89 (а так же в Deno 1.8) появилась возможность использовать Карты импортов (Import maps) – механизма, позволяющего получить контроль над поведением JavaScript-импортов.Несмотря на то, что современная разработка строится с использованием нативных модулей, мы не можем запускать приложения без предварительной сборки. Одна из целей карт импортов как раз решает эту проблему.Если кратко, то теперь можно будет совершенно законно и без всяких сборщиков писать, скажем, так:
import React from 'react';
Под катом разберём как это всё работает.
Для того, чтобы директива import или выражение import() могли разрешать пути к модулям в новом виде, нужно эти пути где-то описать. Да, оказалось никакой магии с подкапотным разрешением зависимостей как в той же Node.js или webpack тут нет.Карты импортов задаются с помощью тега script с атрибутом type="importmap" в формате JSON.А теперь на примере. Запускаем статический сервер (например, с помощью python -m SimpleHTTPServer 9000) и создаём два файла:index.html
<!DOCTYPE html>
<html>
<body>
<script type="importmap">
{
"imports": {
"mylib": "./my-lib.mjs"
}
}
</script>
<script type="module">
import { sayHi } from "mylib";
sayHi();
</script>
</body>
</html>
и my-lib.mjs
export function sayHi() {
console.log("hi!");
}
Открываем в браузере страничку, и вуаля: в консоль вывелось "hi!". Далее более подробно разберём, как оно устроено.СтруктураНа данный момент, согласно спецификации, описывающий зависимости JSON может содержать два ключа: imports и scopes. Если появится какой-то неизвестный ключ, то должно выводиться предупреждение в консоль (хотя у меня Хром этого не делает).ImportsЗначение ключа imports – объект, содержащий в качестве ключей имена модулей (к которым можно обращаться для последующего импорта) и адрес модуля. Адрес должен начинаться с /, ../, ./ или быть абсолютным URL.
"imports": {
"module-name": "address"
}
Также есть возможность описывать "пакеты", содержащие несколько модулей. Для этого нужно к названию ключа добавить / в конец.Создадим директорию "my-pack" добавив в неё index.mjs с содержимым:
export default function mainFunc() {
console.log("text from mainFunc");
}
А также в "my-pack" добавим директорию "some-module" с файлом some-helper.mjs с содержимым:
export function someHelper() {
console.log("text from someHelper");
}
Перепишем importmap нашего index.html:
<script type="importmap">
{
"imports": {
"mypack": "./my-pack/index.mjs",
"mypack/": "./my-pack/"
}
}
</script>
Теперь, кроме обычного импорта основного пакета
import mainFunc from "mypack";
мы также можем получить доступ к его внутренним модулям
import { someHelper } from "mypack/some-module/some-helper.mjs";
ScopesБывают случаи, когда используя один и тот же импорт (точнее, спецификатор импорта), нам нужно получать разные версии библиотеки в зависимости от того, откуда её импортируют. На этот случай и нужны скоупы. Пример:
<script type="importmap">
{
"imports": {
"mypack": "./my-pack/index.mjs",
"mypack/": "./my-pack/"
},
"scopes": {
"some/other/url/": {
"mypack": "./my-pack/index-v2.jsm"
}
}
}
</script>
В данном случае внутри любого модуля, url которого будет начинаться с some/other/url/ импорт "mypack" будет ссылаться на "./my-pack/index-v2.jsm", во всех остальных случаях будет использоваться "./my-pack/index.mjs".Также есть возможность вложенных скоупов. Например:
<script type="importmap">
{
"imports": {
"a": "/a-1.mjs",
"b": "/b-1.mjs",
"c": "/c-1.mjs"
},
"scopes": {
"/scope2/": {
"a": "/a-2.mjs"
},
"/scope2/scope3/": {
"b": "/b-3.mjs"
}
}
}
</script>
Это даст нам такое разрешение путей:SpecifierReferrerResulting URLa/scope1/foo.mjs/a-1.mjsb/scope1/foo.mjs/b-1.mjsc/scope1/foo.mjs/c-1.mjsa/scope2/foo.mjs/a-2.mjsb/scope2/foo.mjs/b-1.mjsc/scope2/foo.mjs/c-1.mjsa/scope2/scope3/foo.mjs/a-2.mjsb/scope2/scope3/foo.mjs/b-3.mjsc/scope2/scope3/foo.mjs/c-1.mjsПодключение карт импортовКак и с остальными ресурсами, подключаемыми через тег script. Можно заполнять содержимое тега:
<script type="importmap">
{
"imports": { ... },
"scopes": { ... }
}
</script>
а можно импортировать карту используя атрибут src:
<script type="importmap" src="some/address/to/import-map.importmap"></script>
Важно, что по этому адресу ответ должен приходить с MIME type application/importmap+json. Особенности
- Карты импортов блокируют остальные запросы импортов, поэтому рекомендуется использовать инлайновый вариант.
- Если добавить карту импорта после использования определения модулей, то это приведёт к ошибке:
An import map is added after module script load was triggered.
- На момент написания этой статьи есть возможность добавить только одну карту импорта. Если добавить вторую, то это приведёт к ошибке. В Хроме выводит следующее:
Multiple import maps are not yet supported. https://crbug.com/927119
DenoВ Deno карты импортов подключаются помощью флага --import-map:deno run --import-map=import_map.json index.ts Где import_map.json - это карта импортов, а index.ts - файл для запуска (компиляции).Источникиhttps://wicg.github.io/import-mapshttps://github.com/WICG/import-mapshttps://deno.land/manual/linking_to_external_code/import_maps
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, VueJS] Сделаем худший Vue.js в мире (перевод)
- [JavaScript, Программирование] Основы JavaScript: почему вы должны знать, как работает JS-движок (перевод)
- [JavaScript, Функциональное программирование] Сочиняя ПО: Введение (перевод)
- [JavaScript, Программирование] 7 вопросов про замыкания в JavaScript (перевод)
- [JavaScript, Анализ и проектирование систем, Алгоритмы, Обработка изображений, Машинное обучение] Мы создали Web приложение для определения лиц и масок для Google Chrome (перевод)
- [Разработка веб-сайтов, JavaScript, ReactJS] Реализация архитектуры Redux на MobX. Часть 2: «Пример на MobX»
- [CSS, JavaScript, HTML] Веб-компоненты проще, чем вы думаете (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование, Проектирование и рефакторинг, ReactJS] Фреймворк-независимое браузерное SPA (перевод)
- [CSS, JavaScript] Заметки фронтендера #1
- [Разработка веб-сайтов, JavaScript, ReactJS] Нарушает ли React DOM-стандарты?
Теги для поиска: #_javascript, #_javascript, #_deno, #_ecmascript, #_javascript
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:43
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Привет. С выходом Chrome 89 (а так же в Deno 1.8) появилась возможность использовать Карты импортов (Import maps) – механизма, позволяющего получить контроль над поведением JavaScript-импортов.Несмотря на то, что современная разработка строится с использованием нативных модулей, мы не можем запускать приложения без предварительной сборки. Одна из целей карт импортов как раз решает эту проблему.Если кратко, то теперь можно будет совершенно законно и без всяких сборщиков писать, скажем, так: import React from 'react';
Для того, чтобы директива import или выражение import() могли разрешать пути к модулям в новом виде, нужно эти пути где-то описать. Да, оказалось никакой магии с подкапотным разрешением зависимостей как в той же Node.js или webpack тут нет.Карты импортов задаются с помощью тега script с атрибутом type="importmap" в формате JSON.А теперь на примере. Запускаем статический сервер (например, с помощью python -m SimpleHTTPServer 9000) и создаём два файла:index.html <!DOCTYPE html>
<html> <body> <script type="importmap"> { "imports": { "mylib": "./my-lib.mjs" } } </script> <script type="module"> import { sayHi } from "mylib"; sayHi(); </script> </body> </html> export function sayHi() {
console.log("hi!"); } "imports": {
"module-name": "address" } export default function mainFunc() {
console.log("text from mainFunc"); } export function someHelper() {
console.log("text from someHelper"); } <script type="importmap">
{ "imports": { "mypack": "./my-pack/index.mjs", "mypack/": "./my-pack/" } } </script> import mainFunc from "mypack";
import { someHelper } from "mypack/some-module/some-helper.mjs";
<script type="importmap">
{ "imports": { "mypack": "./my-pack/index.mjs", "mypack/": "./my-pack/" }, "scopes": { "some/other/url/": { "mypack": "./my-pack/index-v2.jsm" } } } </script> <script type="importmap">
{ "imports": { "a": "/a-1.mjs", "b": "/b-1.mjs", "c": "/c-1.mjs" }, "scopes": { "/scope2/": { "a": "/a-2.mjs" }, "/scope2/scope3/": { "b": "/b-3.mjs" } } } </script> <script type="importmap">
{ "imports": { ... }, "scopes": { ... } } </script> <script type="importmap" src="some/address/to/import-map.importmap"></script>
=========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:43
Часовой пояс: UTC + 5