Плагин @rollup/plugin-virtual предназначен для создания виртуальных модулей, которые не существуют в файловой системе, но могут быть импортированы в сборке Rollup как обычные ES-модули. Это механизм позволяет динамически подставлять содержимое модулей прямо в конфигурации сборщика без необходимости создавать физические файлы.
Основная идея заключается в том, чтобы расширить систему модулей Rollup за пределы файловой системы и дать возможность определять зависимости “на лету”. Виртуальные модули особенно полезны в сценариях генерации кода, тестирования, условной компоновки и интеграции с внешними источниками данных.
Rollup по умолчанию работает с файловой системой: каждый import соответствует реальному файлу. Плагин виртуальных модулей перехватывает процесс разрешения импортов и подменяет его собственными данными.
Ключевые этапы обработки:
В результате импорт вида:
import data from 'virtual:config';
превращается в полноценный модуль, код которого был сгенерирован в памяти сборщика.
Стандартная конфигурация плагина выглядит следующим образом:
import virtual from '@rollup/plugin-virtual';
export default {
input: 'src/main.js',
plugins: [
virtual({
'virtual:config': `
export const name = "app";
export const version = "1.0.0";
`
})
],
output: {
format: 'esm',
file: 'dist/bundle.js'
}
};
В данном примере создаётся виртуальный модуль
virtual:config, экспортирующий две переменные. Он может
быть импортирован в любом месте проекта так же, как обычный файл.
Плагин использует словарь, где ключом выступает строка-маркер модуля, а значением — строка с JavaScript-кодом.
Особенности сопоставления:
virtual:, но
он является распространённой практикойПри попытке импорта Rollup передаёт имя модуля в resolveId. Плагин проверяет наличие совпадения и возвращает идентификатор, который затем используется в load.
Хотя плагин часто используется со статическими строками, его сила раскрывается при генерации содержимого программным способом.
Пример динамической генерации:
virtual({
'virtual:env': (() => {
const env = process.env.NODE_ENV;
return `
export const mode = "${env}";
export const timestamp = ${Date.now()};
`;
})()
})
Здесь код формируется во время инициализации сборщика, что позволяет внедрять параметры окружения без дополнительных loader-ов.
Плагин поддерживает более гибкий подход, когда значение модуля задаётся функцией:
virtual({
'virtual:api': () => {
const baseUrl = 'https://api.example.com';
return `
export const baseUrl = "${baseUrl}";
export const fetchUsers = () => fetch("${baseUrl}/users");
`;
}
})
Такой подход позволяет:
Rollup активно кеширует результаты модулей для ускорения пересборки. Виртуальные модули влияют на этот процесс следующим образом:
Это особенно важно учитывать при использовании
Date.now(), случайных чисел или данных из внешних
источников.
Виртуальные модули часто применяются для централизованной конфигурации:
virtual({
'virtual:config': `
export const config = {
apiUrl: "https://api.example.com",
debug: true,
retries: 3
};
`
})
Преимущество такого подхода заключается в отсутствии необходимости создавать отдельные конфигурационные файлы, а также в возможности переопределять конфигурацию на этапе сборки.
При использовании TypeScript возникает проблема отсутствия типов для виртуальных модулей. Решение заключается в декларации модулей вручную:
declare module 'virtual:config' {
export const name: string;
export const version: string;
}
Это позволяет TypeScript корректно обрабатывать импорты виртуальных модулей и обеспечивать автодополнение.
@rollup/plugin-virtual часто применяется как вспомогательный инструмент в более сложных плагинах. Например:
В архитектуре Rollup он выступает как базовый слой для создания “искусственных” точек входа.
Несмотря на гибкость, виртуальные модули имеют ряд ограничений:
Также важно учитывать, что виртуальный модуль существует только в контексте сборки и не может быть использован в runtime напрямую.
Порядок подключения плагинов влияет на поведение виртуальных модулей.
Обычно @rollup/plugin-virtual размещается ближе к началу
цепочки, чтобы:
При совместном использовании с плагинами трансформации (Babel, TypeScript) виртуальные модули обрабатываются так же, как обычные файлы после стадии загрузки.
Виртуальные модули используются в случаях, когда требуется:
Особенно эффективен подход в монорепозиториях и библиотечных пакетах, где важно минимизировать количество вспомогательных файлов и упростить структуру.