В системе загрузчиков esbuild empty представляет собой
специализированный режим обработки модулей, при котором содержимое файла
полностью исключается из результирующего бандла. Такой модуль сохраняет
только факт импорта, но не вносит ни кода, ни побочных эффектов, ни
экспортов.
Поведение loader empty сводится к следующему: любой
файл, к которому он применён, интерпретируется как пустой модуль. В
процессе сборки его содержимое игнорируется, а на выходе формируется
модуль с нулевой семантической нагрузкой.
При применении loader: "empty" esbuild выполняет
следующие трансформации:
Фактически модуль превращается в эквивалент:
export {}
либо полностью исчезает при дальнейшей оптимизации и tree-shaking, если на него нет ссылок.
Назначение загрузчика выполняется через поле loader в
конфигурации сборки.
import * as esbuild from 'esbuild';
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
loader: {
'.txt': 'empty',
'.md': 'empty'
}
});
В данном примере все файлы с расширениями .txt и
.md будут полностью исключены из бандла.
При встрече импорта:
import doc from './manual.txt';
и наличии конфигурации:
loader: {
'.txt': 'empty'
}
esbuild:
manual.txt;empty;Если импорт предполагает использование значения:
console.log(doc);
значение doc будет undefined либо
оптимизировано до пустого объекта в зависимости от контекста сборки и
настроек minify/tree-shaking.
textLoader text преобразует файл в строку:
loader: { '.txt': 'text' }
import doc from './file.txt';
// doc = "содержимое файла"
fileLoader file копирует файл в выходной каталог и
возвращает URL:
loader: { '.png': 'file' }
emptyLoader empty полностью устраняет содержимое:
loader: { '.txt': 'empty' }
Сравнение поведения:
| Loader | Результат |
|---|---|
| text | строка с содержимым |
| file | путь к файлу |
| empty | отсутствие содержимого |
Loader empty усиливает эффект tree-shaking, так как
модуль становится нейтральным узлом графа зависимостей.
Если модуль содержит только побочные эффекты:
// debug.txt (условно)
console.log("init");
и применяется:
loader: { '.txt': 'empty' }
то:
console.log не попадёт в бандл;При наличии кода вида:
// config.json (условно)
export const value = 42;
и применении:
loader: { '.json': 'empty' }
все экспортируемые значения становятся недоступными. Импорт:
import { value } from './config.json';
приведёт к тому, что value будет неопределённым или
удалённым на этапе оптимизации.
В строгих режимах сборки это может приводить к предупреждениям о неиспользуемых символах.
Loader empty часто применяется для условного исключения
модулей:
esbuild.build({
entryPoints: ['src/app.js'],
bundle: true,
outfile: 'dist/app.js',
loader: {
'.mock.js': 'empty'
}
});
Структура проекта:
src/
api.js
api.mock.js
Импорт:
import api from './api.mock.js';
Результат: модуль api.mock.js полностью исключается.
Плагины esbuild, работающие на уровне onResolve и
onLoad, могут изменять поведение empty.
Типичный сценарий:
plugins: [
{
name: 'conditional-empty',
setup(build) {
build.onLoad({ filter: /\.debug\.js$/ }, () => {
return {
contents: '',
loader: 'js'
};
});
}
}
]
В этом случае loader empty может быть переопределён
логикой плагина, если он срабатывает раньше в цепочке обработки.
Graph traversal в esbuild включает модули с empty
loader, но без анализа содержимого.
Это означает:
Пример:
// a.js
import './b.txt';
export const a = 1;
// b.txt (empty loader)
import { a } from './a.js';
Файл b.txt не будет участвовать в графе импортов,
несмотря на синтаксически валидный импорт внутри.
При включённой минификации (minify: true) пустые
модули:
В результате:
import './noop.txt';
console.log('ok');
может трансформироваться в:
console.log("ok");
Loader empty имеет ряд устойчивых ограничений:
Также важно учитывать, что:
Loader empty используется как механизм управления
видимостью модулей в сборке. Он позволяет:
В крупных проектах он часто выступает как часть стратегии разделения окружений:
esbuild активно кеширует результаты обработки модулей. Для
empty loader это означает:
Это создаёт стабильное поведение в инкрементальных сборках.
При использовании TypeScript:
import config from './config.txt';
и loader empty, тип config фактически
теряет значение. TypeScript может интерпретировать его как
any или undefined, в зависимости от
деклараций.
В JSX-сборках loader empty может использоваться для
исключения вспомогательных файлов:
loader: {
'.stories.js': 'empty'
}
что позволяет удалять storybook-данные из production-бандла.
В ESM:
import x from './file.txt';
результат — пустой модуль без экспорта.
В CommonJS:
const x = require('./file.txt');
возвращаемое значение обычно undefined или пустой
объект, так как esbuild генерирует совместимый shim без содержимого
модуля.
Loader empty используется как инструмент фильтрации на
уровне сборки, а не на уровне кода. Его основная ценность проявляется
в:
Он формирует предсказуемый граф зависимостей, где часть узлов существует только формально, не влияя на результат выполнения.