url() в CSS и особенности обработки при сборкеВ CSS-файлах функция url() используется для указания
внешних ресурсов: изображений, шрифтов, иконок, медиафайлов. При ручной
разработке браузер интерпретирует пути относительно расположения
итогового CSS-файла или документа. Однако при использовании сборщика,
такого как Esbuild, эта логика меняется, поскольку исходные файлы часто
перемещаются, минифицируются и складываются в другие директории.
Основная сложность обработки url() в процессе сборки
заключается в необходимости:
Esbuild решает эти задачи через систему загрузчиков (loaders) и встроенную обработку CSS.
url()При обработке CSS Esbuild анализирует все конструкции вида:
background-image: url("./images/bg.png");
Дальнейшее поведение зависит от конфигурации:
По умолчанию Esbuild старается сохранить корректность путей, но оптимизирует структуру выходных файлов.
При стандартной конфигурации изображения и шрифты копируются в
outdir, а ссылки переписываются:
/* исходный CSS */
background: url("./img/logo.png");
После сборки:
background: url("assets/logo-3f2a1c.png");
Esbuild автоматически:
При использовании loader dataurl ресурсы преобразуются в
строку base64:
esbuild.build({
entryPoints: ["style.css"],
bundle: true,
loader: {
".png": "dataurl"
}
});
Результат:
background: url("data:image/png;base64,iVBORw0KGgoAAA...");
Преимущества:
Недостатки:
file
loaderРежим file сохраняет файл отдельно и возвращает
путь:
loader: {
".png": "file"
}
Результат:
background: url("image-9d8f1c.png");
Особенности:
url() путиПри обработке CSS Esbuild выполняет несколько шагов:
Анализируются все конструкции:
url("...")url('...')url(...)Даже без кавычек пути корректно извлекаются.
Путь интерпретируется относительно исходного CSS-файла:
styles/main.css
assets/bg.png
background: url("../assets/bg.png");
В зависимости от расширения файла:
.png, .jpg → file/dataurl.woff, .woff2 → file/dataurl.svg → file/dataurl или textEsbuild заменяет исходный путь на новый, рассчитанный после сборки.
url()Шрифты обрабатываются аналогично изображениям:
@font-face {
font-family: "Inter";
src: url("./fonts/Inter.woff2") format("woff2");
}
После сборки:
@font-face {
font-family: "Inter";
src: url("assets/Inter-a1b2c3.woff2") format("woff2");
}
При использовании dataurl:
src: url("dat a:font/woff2;base64,d09GMgABAAAA...");
url()При включённой минификации Esbuild:
url();Пример:
background-image: url( "./img/bg.png" );
Становится:
background-image:url("img/bg.png");
outdir
и структуры проектаВыходная директория напрямую влияет на итоговые пути.
esbuild.build({
entryPoints: ["src/index.css"],
outdir: "dist",
bundle: true,
loader: {
".png": "file"
}
});
dist/index.cssdist/assets/Esbuild автоматически пересчитывает относительность.
background: url("/images/bg.png");
Такие пути:
Это важно при миграции проектов, где ранее использовался webpack alias или public folder.
Несмотря на высокую скорость, есть особенности:
url()
без плагинов;url()Esbuild предоставляет plugin API для контроля над тем, как обрабатываются ресурсы.
Пример плагина:
const urlPlugin = {
name: "url-plugin",
setup(build) {
build.onResolve({ filter: /\.(png|jpg)$/ }, args => {
return { path: args.path, namespace: "asset" };
});
build.onLoad({ filter: /.*/, namespace: "asset" }, args => {
return {
contents: "",
loader: "file"
};
});
}
};
С помощью плагинов можно:
url() внутри @import и CSS ModulesEsbuild также анализирует CSS зависимости, включая:
@import "./theme.css";
И внутри импортируемых файлов:
.icon {
background: url("./icon.svg");
}
При использовании CSS Modules:
url() остаётся зависимостью сборщика.Esbuild может добавлять хеши к файлам:
image.png → image-a1b2c3.png
Это влияет на url():
url()Одно из ключевых преимуществ Esbuild:
url() выполняется на уровне
Go-реализации;Это делает обработку:
Esbuild обеспечивает автоматическое управление зависимостями через
url().
При публикации пакетов важно:
При code splitting:
url() зависимости;url() в Esbuildfile и dataurl без
стратегии;outdir при построении CSS.outdir для CSS и ассетов;url() логики.