@rollup/plugin-json

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

Плагин @rollup/plugin-json предоставляет такую возможность. Он преобразует JSON-файлы в полноценные JavaScript-модули, которые могут участвовать в дереве зависимостей Rollup наравне с обычными ES-модулями.

После подключения плагина становится возможным использовать конструкции вида:

import config from './config.json';

console.log(config.apiUrl);

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


Установка

Плагин устанавливается через npm:

npm install @rollup/plugin-json --save-dev

или через Yarn:

yarn add @rollup/plugin-json --dev

или через pnpm:

pnpm add -D @rollup/plugin-json

Базовое подключение

Наиболее простой вариант настройки выглядит следующим образом:

import json from '@rollup/plugin-json';

export default {
    input: 'src/index.js',

    output: {
        file: 'dist/bundle.js',
        format: 'esm'
    },

    plugins: [
        json()
    ]
};

Теперь Rollup сможет импортировать любые JSON-файлы внутри проекта.


Пример структуры проекта

Структура файлов:

src/
├── index.js
└── settings.json

Содержимое settings.json:

{
    "host": "localhost",
    "port": 3000,
    "debug": true
}

Содержимое index.js:

import settings from './settings.json';

console.log(settings.host);
console.log(settings.port);
console.log(settings.debug);

Во время сборки Rollup преобразует JSON в JavaScript-модуль.

Фактически внутри бандла может появиться код наподобие:

var settings = {
    host: 'localhost',
    port: 3000,
    debug: true
};

console.log(settings.host);

Как работает преобразование JSON

JSON-файл сам по себе не является JavaScript-модулем.

Например:

{
    "title": "Rollup Guide",
    "version": "1.0"
}

Плагин генерирует из него модуль:

var title = 'Rollup Guide';
var version = '1.0';

var data = {
    title,
    version
};

export { title, version };
export default data;

Благодаря этому становится возможным использовать как импорт по умолчанию, так и именованные импорты.


Импорт по умолчанию

Наиболее распространённый вариант работы:

import packageInfo from './package.json';

console.log(packageInfo.name);
console.log(packageInfo.version);

Здесь весь JSON импортируется как единый объект.

Такой подход особенно удобен для:

  • конфигурационных файлов;
  • языковых словарей;
  • файлов локализации;
  • статических данных;
  • настроек приложения;
  • метаданных проекта.

Именованные импорты

Одной из полезных особенностей плагина является возможность создавать именованные экспорты.

JSON:

{
    "name": "my-app",
    "version": "1.0.0",
    "author": "Admin"
}

Импорт:

import { name, version } from './package.json';

console.log(name);
console.log(version);

Такой подход позволяет Rollup эффективнее выполнять tree shaking.

Если используется только поле name, остальные поля могут быть удалены из итогового бандла.


Tree Shaking для JSON

Предположим, имеется файл:

{
    "name": "Application",
    "version": "2.0.0",
    "author": "Admin",
    "license": "MIT",
    "repository": "github"
}

Импортируется только одно свойство:

import { name } from './package.json';

console.log(name);

После анализа зависимостей Rollup может исключить неиспользуемые поля.

Результирующий код становится значительно меньше:

var name = 'Application';

console.log(name);

Для крупных JSON-файлов это может заметно уменьшить размер итоговой сборки.


Опция namedExports

По умолчанию плагин создаёт именованные экспорты.

Явная настройка:

json({
    namedExports: true
})

Пример использования:

import { port } from './settings.json';

console.log(port);

Если параметр отключён:

json({
    namedExports: false
})

То доступен только импорт по умолчанию:

import settings from './settings.json';

А такой код станет ошибочным:

import { port } from './settings.json';

Опция compact

Параметр compact влияет на формат генерируемого кода.

Стандартный вариант:

json({
    compact: false
})

Сгенерированный модуль может выглядеть так:

var name = 'Application';

var data = {
    name: name
};

export default data;

Компактный режим:

json({
    compact: true
})

Результат становится более сжатым:

var name="Application";var data={name:name};export default data;

Подобная настройка полезна для уменьшения объёма промежуточного кода.


Опция preferConst

По умолчанию значения могут создаваться через var.

Настройка:

json({
    preferConst: true
})

Позволяет генерировать:

const version = '1.0.0';

вместо:

var version = '1.0.0';

Преимущества:

  • более современный код;
  • улучшенная оптимизация;
  • лучшая читаемость промежуточных файлов;
  • дополнительная помощь инструментам анализа.

Опция indent

Позволяет управлять форматированием сгенерированного объекта.

Пример:

json({
    indent: '    '
})

Генерируемый код:

var config = {
    name: 'Application',
    version: '1.0.0'
};

При использовании:

json({
    indent: '\t'
})

Для форматирования применяются табуляции.

Данная настройка полезна главным образом при анализе промежуточного вывода сборки.


Опция include

Позволяет ограничить набор файлов, обрабатываемых плагином.

Например:

json({
    include: 'src/data/**/*.json'
})

Будут обработаны только JSON-файлы внутри каталога src/data.

Также можно использовать массив шаблонов:

json({
    include: [
        'src/config/**/*.json',
        'src/data/**/*.json'
    ]
})

Опция exclude

Позволяет исключить часть файлов из обработки.

Пример:

json({
    exclude: 'src/temp/**/*.json'
})

или:

json({
    exclude: [
        'src/temp/**',
        'src/backup/**'
    ]
})

Подобная фильтрация особенно полезна в крупных проектах с большим количеством служебных данных.


Совместное использование include и exclude

Часто обе настройки применяются одновременно:

json({
    include: 'src/**/*.json',
    exclude: [
        'src/tests/**',
        'src/temp/**'
    ]
})

В таком случае:

  • все JSON внутри src разрешены;
  • каталоги тестов исключаются;
  • временные данные игнорируются.

Работа с package.json

Один из самых популярных сценариев использования.

Файл:

{
    "name": "awesome-library",
    "version": "3.2.0"
}

Импорт:

import pkg from '../package.json';

console.log(pkg.name);
console.log(pkg.version);

Либо:

import { version } from '../package.json';

console.log(version);

Такой подход часто применяется для автоматического внедрения версии приложения во время сборки.


Создание баннера с версией

import { version } from '../package.json';

export const APP_VERSION = version;

Затем:

console.log(`Version: ${APP_VERSION}`);

Во многих библиотеках именно таким образом отображается текущая версия сборки.


Работа с файлами локализации

Структура:

locales/
├── en.json
├── ru.json
└── de.json

Файл:

{
    "welcome": "Добро пожаловать",
    "logout": "Выход"
}

Импорт:

import ru from './locales/ru.json';

console.log(ru.welcome);

Плагин позволяет использовать словари перевода без дополнительных загрузчиков и преобразователей.


Использование в библиотеках

JSON часто хранит:

  • наборы констант;
  • таблицы соответствий;
  • справочники;
  • данные кодировок;
  • языковые словари;
  • настройки по умолчанию.

Например:

{
    "USD": "US Dollar",
    "EUR": "Euro",
    "KZT": "Kazakhstani Tenge"
}

Импорт:

import currencies from './currencies.json';

После сборки данные становятся частью JavaScript-кода библиотеки.


Ограничения при работе с большими JSON

Хотя плагин отлично справляется с обычными файлами конфигурации, следует учитывать особенности крупных наборов данных.

Например:

[
    {...},
    {...},
    {...}
]

размером в десятки мегабайт.

После преобразования:

  • содержимое полностью попадёт в бандл;
  • увеличится время сборки;
  • возрастёт объём памяти;
  • размер итогового файла станет существенно больше.

Для очень больших наборов данных часто предпочтительнее:

  • загружать JSON по сети;
  • использовать динамический импорт;
  • хранить данные во внешнем файле;
  • получать информацию через API.

Использование вместе с другими плагинами

Чаще всего @rollup/plugin-json применяется совместно с:

plugins: [
    nodeResolve(),
    commonjs(),
    json()
]

Такой набор обеспечивает:

  • разрешение модулей из node_modules;
  • поддержку CommonJS;
  • импорт JSON-файлов.

Подобная конфигурация встречается в большинстве проектов на Rollup.


Типичные ошибки

Отсутствует подключение плагина

Код:

import config from './config.json';

Ошибка:

Unexpected token

Причина заключается в том, что Rollup не умеет обрабатывать JSON без соответствующего плагина.


Неверный путь

import data from './configs.json';

Если файл отсутствует:

Could not resolve './configs.json'

Следует проверить расположение файла и корректность пути.


Использование именованного импорта при отключённых экспортируемых полях

Конфигурация:

json({
    namedExports: false
})

Импорт:

import { version } from './package.json';

Результатом станет ошибка разрешения экспорта.


Практические сценарии применения

Наиболее распространённые случаи использования @rollup/plugin-json:

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

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