Механизм загрузчиков в esbuild опирается на правило сопоставления расширений файлов с конкретными стратегиями обработки. Каждый тип ресурса — JavaScript, TypeScript, JSON, CSS, изображения — получает собственный pipeline трансформации, определяемый через параметр loader. Для CSS это особенно важно, поскольку поведение отличается от привычной модели JavaScript-модулей и напрямую влияет на глобальность стилей в приложении.
Для файлов .css используется встроенный загрузчик
css, который изменяет стандартную семантику импорта:
import './styles.css'
Такой импорт не приводит к получению объекта в JavaScript-коде. Вместо этого esbuild рассматривает CSS как побочный эффект, который должен быть включён в итоговую сборку.
Базовая настройка:
import * as esbuild from 'esbuild'
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/app.js',
loader: {
'.css': 'css'
}
})
При такой конфигурации CSS становится частью графа зависимостей и перестаёт быть внешним ресурсом.
Понятие глобального CSS в контексте esbuild означает отсутствие
изоляции стилей между модулями. Любой импортированный файл
.css влияет на общий DOM без ограничений области
видимости.
Ключевая особенность заключается в том, что esbuild не реализует автоматическую инкапсуляцию классов. Все селекторы остаются в исходном виде:
.button {
background: black;
color: white;
}
После сборки этот стиль применяется ко всем элементам
.button в документе без привязки к конкретному модулю.
При использовании CSS внутри JavaScript-модулей esbuild превращает
импорт в побочный эффект. В браузерной сборке это реализуется через
генерацию кода, который динамически добавляет <style>
в документ:
// псевдогенерируемый результат
var css = "body { margin: 0; }";
var style = document.createElement("style");
style.textContent = css;
document.head.appendChild(style);
Такой подход делает CSS глобально применимым без необходимости
отдельного подключения через <link>.
Esbuild по умолчанию не включает механизм CSS Modules. Это означает, что отсутствует переименование классов и локализация области видимости.
Глобальный CSS:
.title {
font-size: 20px;
}
CSS Modules (не встроены в esbuild без плагинов):
.title {
font-size: 20px;
}
В модульной системе класс .title трансформируется в
уникальный идентификатор, например:
.title_ab12x {
font-size: 20px;
}
и доступ осуществляется через импорт:
import styles from './styles.module.css'
console.log(styles.title)
В esbuild для этого используются сторонние плагины, поскольку базовый
loader css ориентирован именно на глобальное поведение.
Наиболее распространённая конфигурация предполагает единый глобальный слой стилей:
esbuild.build({
entryPoints: ['src/main.js'],
bundle: true,
outdir: 'dist',
loader: {
'.css': 'css'
},
splitting: true,
format: 'esm'
})
При этом все CSS-файлы, импортируемые из разных частей приложения, объединяются в общий набор стилей.
Глобальный CSS в esbuild подчиняется стандартным правилам каскада. Порядок импорта определяет итоговую приоритетность правил:
import './reset.css'
import './theme.css'
import './components/button.css'
CSS будет применён в том же порядке, что и импорт в графе зависимостей. Последние импортированные стили могут переопределять предыдущие при равной специфичности селекторов.
CSS в esbuild считается ресурсом с побочными эффектами. Это означает, что даже если файл импортирован косвенно, он не удаляется из сборки:
import './global.css'
Удаление такого импорта невозможно без явного анализа side effects, поскольку визуальное состояние приложения зависит от его выполнения.
Глобальный CSS часто используется в базовых слоях приложения:
Пример структуры:
src/
styles/
reset.css
variables.css
global.css
components/
header/
header.js
header.css
Импорт глобального слоя обычно выполняется в точке входа:
import './styles/reset.css'
import './styles/variables.css'
import './styles/global.css'
import './app.js'
Глобальный CSS часто опирается на использование CSS-переменных:
:root {
--primary-color: #3366ff;
--font-size-base: 16px;
}
Такой подход хорошо сочетается с esbuild, поскольку стили не изолируются и переменные доступны во всём DOM без дополнительных механизмов проброса.
Несмотря на простоту, загрузчик css в esbuild имеет ряд
ограничений:
Для расширения функциональности подключаются плагины:
В production-режиме esbuild оптимизирует CSS следующим образом:
Однако глобальность сохраняется неизменной: стили продолжают применяться ко всему документу без ограничений области видимости.
При использовании code splitting CSS может быть разбит по чанкам, соответствующим точкам входа:
esbuild.build({
entryPoints: ['src/pageA.js', 'src/pageB.js'],
bundle: true,
splitting: true,
format: 'esm',
outdir: 'dist',
loader: {
'.css': 'css'
}
})
Каждый чанк получает свой набор глобальных стилей, которые загружаются вместе с соответствующим JavaScript-модулем, что приводит к поэтапному применению CSS в приложении.
В приложениях с компонентной структурой глобальный CSS обычно выполняет роль нижнего слоя:
Поверх него могут накладываться локальные стили компонентов, даже если они не изолированы системой модулей. В такой модели важно учитывать приоритет и порядок подключения, поскольку конфликт селекторов разрешается исключительно каскадом, а не системой именования.