output.path определяет абсолютный путь в файловой
системе, куда Webpack записывает собранные файлы после выполнения
сборки. Это базовая настройка, от которой зависит физическое
расположение итогового бандла и всех вспомогательных ассетов.
Ключевое ограничение: значение output.path всегда должно
быть абсолютным путём. Относительные пути не
допускаются, так как Webpack должен точно понимать, куда писать файлы
независимо от текущей рабочей директории процесса.
Типичный пример:
const path = require('path');
module.exports = {
output: {
path: path.resolve(__dirname, 'dist')
}
};
Здесь используется path.resolve, который формирует
абсолютный путь на основе текущего расположения конфигурационного файла.
Конструкция __dirname гарантирует стабильность независимо
от того, откуда запускается сборка.
Во время компиляции Webpack формирует граф модулей, после чего
сериализует результат в набор файлов. Именно output.path
определяет:
Если директория не существует, Webpack создаёт её автоматически.
В development-режиме output.path часто указывает на
локальную папку вроде dist или build, но
физическая запись файлов может быть частично абстрагирована
webpack-dev-server, который отдаёт файлы из памяти.
В production-режиме значение становится критически важным, так как именно сюда попадают финальные артефакты, которые затем публикуются на сервере или CDN.
output.publicPath определяет базовый URL, по которому
приложение будет обращаться к собранным файлам во время выполнения в
браузере.
Если output.path отвечает за файловую систему, то
publicPath отвечает за сетевой путь
(URL).
Пример:
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/assets/'
}
};
В этом случае все динамически подгружаемые ресурсы будут запрашиваться по адресу:
/assets/main.js
/assets/0.chunk.js
/assets/image.png
Важно различать эти параметры:
output.path — где файлы физически лежат на дискеoutput.publicPath — откуда браузер их загружаетОни могут совпадать, но часто различаются в реальных проектах, особенно при использовании CDN.
output: {
publicPath: './'
}
Используется в случаях, когда приложение разворачивается в произвольной директории, например как статический сайт без строгого корня домена.
Минус такого подхода — зависимость от текущего URL страницы, что может приводить к ошибкам при роутинге SPA.
output: {
publicPath: '/'
}
Самый распространённый вариант для SPA-приложений. Все ресурсы загружаются от корня домена:
https://example.com/main.js
output: {
publicPath: 'https://cdn.example.com/assets/'
}
В этом случае Webpack не просто собирает файлы, но и “знает”, что в runtime они будут загружаться с внешнего сервера.
Это особенно важно для:
В некоторых случаях publicPath нельзя зафиксировать на
этапе сборки. Тогда используется runtime-определение:
__webpack_public_path__ = window.CDN_URL;
или:
__webpack_public_path__ = '/assets/';
Это позволяет менять источник загрузки файлов в зависимости от окружения, пользователя или конфигурации сервера.
При использовании динамического импорта:
import('./module.js');
Webpack создаёт отдельный чанк. Путь к нему формируется на основе
publicPath.
Если publicPath указан неверно, браузер попытается
загрузить chunk по неправильному адресу, что приводит к ошибкам:
ChunkLoadError: Loading chunk failed
При генерации HTML-файла через плагин:
new HtmlWebpackPlugin({
template: './src/index.html'
});
publicPath используется для автоматической вставки
<script> и <link> тегов:
<script src="/assets/main.js"></script>
Если publicPath меняется, HTML автоматически
адаптируется без ручного редактирования путей.
В dev-сервере publicPath определяет виртуальный базовый
URL, с которого сервер отдаёт бандлы из памяти.
Пример:
devServer: {
static: './dist',
devMiddleware: {
publicPath: '/assets/'
}
}
В этом случае ресурсы доступны по:
http://localhost:8080/assets/main.js
При этом физически файлов на диске может не быть — они находятся в памяти.
При использовании Asset Modules:
module: {
rules: [
{
test: /\.(png|jpg|svg)$/,
type: 'asset/resource'
}
]
}
Webpack генерирует URL для каждого файла на основе
publicPath:
output: {
publicPath: '/static/'
}
Результат:
/static/image.hash.png
Если publicPath не задан, используется значение по
умолчанию — относительный путь.
Файлы физически лежат в /dist, но приложение пытается
загрузить их с /assets/, что приводит к 404.
publicPath: '/assets' // потенциально проблемный вариант
Webpack может неправильно склеивать пути:
/assetsmain.js
Корректный вариант:
publicPath: '/assets/'
publicPath: './'
При переходе на маршруты вида /dashboard/settings
браузер может попытаться загрузить:
/dashboard/assets/main.js
что приводит к ошибкам загрузки.
При использовании [contenthash]:
output: {
filename: '[name].[contenthash].js',
publicPath: '/assets/'
}
формируется стабильная система кеширования:
output.path определяет, где хранится файлpublicPath определяет, как он доступен извнеcontenthash обеспечивает уникальность версииЭто позволяет CDN и браузеру эффективно кэшировать ресурсы без конфликтов при обновлениях.
Webpack внедряет механизм подстановки пути прямо в runtime загрузчик модулей. Это влияет на:
Любое изменение publicPath напрямую влияет на логику
загрузчика, а не только на строки URL в HTML.
Внутренний runtime Webpack использует publicPath как
базовый префикс:
__webpack_require__.p = "/assets/";
После этого каждый динамический запрос строится относительно этого
значения. Это делает publicPath одним из ключевых
параметров рантайма, а не только конфигурации сборки.
В MPA-сценариях часто применяются разные publicPath для
разных точек входа:
output: {
publicPath: '/app1/'
}
или через динамическую подмену в зависимости от entry.
Это позволяет размещать несколько приложений в рамках одного домена:
/app1/
/app2/
В продакшене часто используется комбинация:
output.path: локальная сборкаpublicPath: CDN URLoutput: {
path: path.resolve(__dirname, 'dist'),
publicPath: 'https://cdn.example.com/v1/'
}
Это обеспечивает независимость между процессом сборки и инфраструктурой доставки.
При смене CDN достаточно изменить publicPath, не трогая
код приложения.
В серверном рендеринге publicPath должен совпадать с
тем, как сервер отдаёт статику клиенту. Несовпадение приводит к тому,
что HTML сгенерирован корректно, но клиент не может загрузить
JS-бандлы.
В SSR часто используется переменная окружения:
publicPath: process.env.ASSET_PREFIX
что позволяет разделить окружения: