Импорт JSON в ES-модулях (без Fetch, без бандлера)
Если вы когда-либо пытались использовать import config from './config.json' в проекте с обычными ES-модулями и натыкались на стену, вы не одиноки. Годами импорт JSON без бандлера означал возврат к fetch() или преобразование данных в JavaScript-файл. Эра таких обходных путей закончилась.
По состоянию на 2025 год атрибуты импорта являются базовыми во всех современных браузерах. Теперь вы можете выполнять нативный импорт JSON-модулей в JavaScript без каких-либо инструментов сборки.
Ключевые моменты
- Используйте
with { type: 'json' }для нативного импорта JSON в ES-модулях — без бандлера илиfetch(). - Атрибут
typeобязателен по соображениям безопасности: он гарантирует, что среда выполнения проверит MIME-тип перед обработкой файла. - JSON-модули предоставляют только экспорт по умолчанию. Деструктурируйте из него после импорта.
- Ваши JSON-файлы должны передаваться по HTTP с корректным заголовком
Content-Type: application/json.
Современный синтаксис: атрибуты импорта
Текущий синтаксис использует ключевое слово with для объявления типа модуля:
// Static import
import config from './config.json' with { type: 'json' }
console.log(config.apiUrl)
Для динамической загрузки:
// Dynamic import
const { default: config } = await import('./config.json', {
with: { type: 'json' }
})
Примечание: Старый синтаксис
assert { type: 'json' }(поддерживался в Chrome 91–122) теперь устарел. Всегда используйтеwith.
Почему атрибут type: 'json' обязателен
Атрибут with { type: 'json' } — это не опциональное украшение. Он служит конкретной цели безопасности: он заставляет браузер или среду выполнения проверить MIME-тип ответа как application/json перед обработкой чего-либо.
Без него сервер мог бы вернуть JavaScript, замаскированный под JSON-файл, и движок не имел бы способа обеспечить различие. Атрибут типа предотвращает это.
JSON-модули имеют только экспорт по умолчанию
Один момент, который сбивает разработчиков с толку: JSON-модули не поддерживают именованные экспорты. Весь JSON-объект поступает как экспорт по умолчанию.
import data from './data.json' with { type: 'json' }
// ✅ Правильно
const { users, settings } = data
// ❌ Это не сработает
import { users } from './data.json' with { type: 'json' }
Деструктурируйте из экспорта по умолчанию после импорта.
Discover how at OpenReplay.com.
Поддержка в браузерах и Node.js
| Окружение | Минимальная версия |
|---|---|
| Chrome | 123+ |
| Firefox | 138+ |
| Safari | 17.2+ |
| Node.js | Текущий LTS и новее |
Все они сейчас широко распространены. Если вы ориентируетесь на современные браузеры и актуальные релизы Node.js, вам не нужен бандлер или вызов fetch() для загрузки JSON.
Примечание: Более ранние версии Node.js предоставляли JSON-модули за экспериментальными флагами. Поддержка JSON-модулей с атрибутами импорта теперь стабильна в текущих релизах Node.js. См. документацию Node.js ESM для точных деталей по версиям.
Практические ограничения, которые нужно знать перед развертыванием
Вам нужен HTTP-сервер. Импорт модулей — включая JSON-модули — обычно не работает при загрузке страниц напрямую через file://. Браузеры применяют строгие правила безопасности к загрузке модулей. Используйте локальный dev-сервер, такой как Vite, serve или любой сервер статических файлов.
Ваш JSON-файл должен передаваться с корректным MIME-типом. Сервер должен возвращать Content-Type: application/json. Большинство серверов статических файлов обрабатывают это автоматически для .json файлов, но перепроверьте, если вы используете пользовательский сервер или конфигурацию CDN.
JSON должен быть валидным. На уровне импорта нет восстановления после ошибок. Синтаксическая ошибка в вашем JSON-файле приведет к полному сбою загрузки модуля. Валидируйте ваш JSON перед развертыванием.
Практический пример
// config.json
{
"apiUrl": "https://api.example.com",
"timeout": 5000,
"features": {
"darkMode": true
}
}
// app.js
import config from './config.json' with { type: 'json' }
const { apiUrl, timeout, features } = config
if (!apiUrl || typeof timeout !== 'number') {
throw new Error('Invalid configuration')
}
Этот паттерн хорошо работает для конфигурационных файлов, флагов функций, строк интернационализации или любых статических структурированных данных, которые нужны вашему приложению при запуске.
Заключение
Атрибуты импорта дают вам чистый, нативный способ импортировать JSON в ES-модулях без fetch(), без бандлера и без обходных путей. Синтаксис with { type: 'json' } теперь широко поддерживается в современных браузерах и текущих релизах Node.js. Просто убедитесь, что ваши файлы передаются по HTTP с правильным MIME-типом, и всё готово.
Часто задаваемые вопросы
Да. Предложение атрибутов импорта разработано с возможностью расширения. CSS-модули, например, используют with type css в поддерживающих браузерах. Однако JSON — это наиболее широко поддерживаемый тип на сегодняшний день. Другие типы зависят от среды выполнения и могут быть еще не доступны повсеместно.
Импорт полностью провалится и выбросит SyntaxError. В отличие от fetch, где вы можете перехватить и проверить сырой ответ, импорт JSON-модуля не предлагает частичного восстановления. Валидируйте ваши JSON-файлы с помощью линтера или CI-проверки перед развертыванием, чтобы избежать незаметных сбоев при загрузке.
Не для самого импорта JSON. Современные браузеры и Node.js обрабатывают это нативно. Однако вам может понадобиться бандлер по другим причинам, таким как разделение кода, tree shaking или транспиляция синтаксиса для более старых целевых платформ. Суть в том, что загрузка JSON сама по себе больше не требует бандлера.
Браузеры применяют строгие правила безопасности к загрузке модулей. Протокол file не поддерживает механизмы, необходимые для запросов модулей, поэтому браузер блокирует импорт. Вам нужно передавать файлы через HTTP-сервер, даже локально. Инструменты, такие как Vite или npm-пакет serve, справляются с этим с минимальной настройкой.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.