Модули JSON предназначены для приложений, состоящих из модулей JavaScript. Модули JSON позволяют загружать статические или динамически сгенерированные данные во время загрузки модулей JavaScript. С модулями JSON модули ES стали меньше уступать модулям AMD.

Вариантов использования модулей JSON может быть много, но я опишу, как они упрощают задачу, с которой я регулярно сталкиваюсь. В некоторых веб-приложениях макет или содержимое стартовой страницы зависят от некоторых настроек, например привилегий или предпочтений пользователя. Перед рендерингом стартовой страницы такие приложения должны загрузить некоторые исходные данные, специфичные для клиента.

Для простоты давайте представим приложение, которому требуется имя пользователя для размещения стартовой страницы. После отображения начальной страницы с некоторым базовым содержимым приложение загружает и отображает дополнительные данные. Точкой входа в пример приложения является простой файл main.js:

// main.js
import layout from './init/layoutUser.js';
import loadAndRenderData from './init/loadAndRenderData.js';
layout();
loadAndRenderData();

loadAndRenderData() вызывается после того, как пользовательское начальное представление было создано layout(). Обратите внимание, что код прост и не содержит промисов.

Как загрузить JSON в модуль JavaScript?

В приведенном выше коде модуль layoutUser.js экспортирует функцию, которая отображает пустую стартовую страницу и подключает прослушиватели событий.

// layoutUser.js
import renderStartPage from './renderStartPage.js';  
import attachListeners from './attachListeners.js';
import user from 'api/user.json' assert { type: "json" };
export default ()=>{
    renderStartPage(user);
    attachListeners();
};

Пользовательский макет создается функцией renderStartPage(user), для которой требуются пользовательские данные. Опять же, обратите внимание на простоту кода модуля — он лаконичный и без fetch с промисами. Перед началом выполнения модуля сведения о пользователе загружаются из ресурса REST и анализируются в объекте, который назначается константе user.

Импорт модуля JSON выглядит как импорт модуля JavaScript, но с добавленным утверждением типа MIME:

import user from 'api/user.json' assert { type: "json" };

URL-адрес JSON не обязательно должен заканчиваться на .json, он может быть любым (например, api/user), но его тип содержимого должен соответствовать типу MIME JSON application/json. Импорт JSON без утверждения типа или импорт JSON с типом контента, отличным от application/json, приводит к ошибке.

Совместимость с браузером

Пока что только пользователи самого популярного браузера могут пользоваться этой функцией модулей JSON. Он включен в Chrome, начиная с версии 91.

json — единственный тип модуля, поддерживаемый в настоящее время утверждениями импорта. Но есть планы по внедрению также модулей CSS и HTML.

Предыдущий способ импорта JSON в модули JavaScript

До внедрения модулей JSON верхний уровень await для fetch был самым простым вариантом для загрузки JSON в модуль JavaScript. И это остается самым простым способом импорта любого текстового ресурса (подробнее об этом https://marian-caikovski.medium.com/how-to-import-html-template-file-into-javascript-module-265746167974). Давайте посмотрим, как вышеприведенный модуль layoutUser.js выглядел бы без импорта модуля JSON.

import renderStartPage from './renderStartPage.js';
import attachListeners from './attachListeners.js';
const user = await fetch('api/user.json')
    .then(response => response.json());
export default ()=>{
    renderStartPage(user);
    attachListeners();
};

Код немного длиннее, но принцип тот же. Выполнение модуля, как и выполнение его родителей, приостанавливается до получения ожидаемого JSON (подробнее о порядке выполнения модулей ES6). Выполнение модуля возобновляется после того, как JSON анализируется в объект и присваивается константе user.

До того, как был реализован верхний уровень await, загрузка ресурсов в модули была асинхронным испытанием, которое больше не нужно было вызывать.

Полный образец кода можно загрузить с https://github.com/marianc000/JSONModule.git и запустить в браузере Chrome.