BannerPlugin относится к стандартному набору плагинов Webpack и используется для добавления произвольного текстового комментария в начало выходных файлов. Чаще всего применяется для вставки лицензионной информации, авторских прав, версий сборки, служебных меток окружения или идентификаторов билда.
Механизм работы основан на перехвате этапа генерации чанков и модификации итогового исходного кода до записи на диск. Плагин работает на уровне компиляции и не влияет на модульную систему или runtime-логику приложения.
Основная задача заключается в автоматическом внедрении текстового баннера в результирующие файлы JavaScript и CSS (при соответствующей настройке сборки). Баннер представляет собой строковый комментарий, который добавляется в начало каждого чанка.
Типовые сценарии использования:
Встраивание выполняется на этапе оптимизации ассетов, когда код уже собран, но ещё не записан в файловую систему.
Подключение осуществляется через импорт из webpack:
const webpack = require('webpack');
Использование в конфигурации:
module.exports = {
plugins: [
new webpack.BannerPlugin('Build version 1.0.0')
]
};
В результате каждый выходной файл начнётся с комментария:
/*! Build version 1.0.0 */
Webpack автоматически оборачивает строку в комментарий формата
/*! ... */, который сохраняется даже при минимизации (в
большинстве режимов terser не удаляет такие комментарии).
BannerPlugin поддерживает несколько типов источников данных для формирования строки.
Самый простой вариант — фиксированная строка:
new webpack.BannerPlugin({
banner: 'Static banner text'
})
Подходит для неизменяемых значений, например лицензий.
Позволяет динамически формировать текст на основе метаданных сборки:
new webpack.BannerPlugin({
banner: () => {
return `Build time: ${new Date().toISOString()}`;
}
})
Функция вызывается во время компиляции, что позволяет учитывать состояние окружения.
Функция может принимать аргумент webpack и
compilation:
new webpack.BannerPlugin({
banner: (options) => {
return `Hash: ${options.hash}`;
}
})
Доступные данные:
BannerPlugin позволяет контролировать формат оборачивания текста.
Отключает автоматическое оборачивание в комментарий:
new webpack.BannerPlugin({
banner: 'console.log("test")',
raw: true
})
В этом случае содержимое вставляется как есть. Используется редко, так как может нарушить структуру итогового бандла.
При длинных баннерах формируется блочный комментарий:
new webpack.BannerPlugin({
banner: `
Author: Dev Team
License: MIT
Internal build
`
})
Webpack преобразует это в единый комментарий с сохранением переносов строк.
BannerPlugin может использовать функцию, возвращающую строку, что делает возможным подключение внешних данных.
Пример с package.json:
const packageJson = require('./package.json');
new webpack.BannerPlugin({
banner: `name: ${packageJson.name} version: ${packageJson.version}`
})
Также возможно использование ENV переменных:
new webpack.BannerPlugin({
banner: () => {
return `ENV: ${process.env.NODE_ENV}`;
}
})
При использовании TerserPlugin важно учитывать поведение комментариев.
По умолчанию:
/*! ... */ сохраняются// и /* ... */ удаляютсяBannerPlugin использует защищённый формат комментариев, поэтому:
Однако при агрессивной оптимизации можно столкнуться с удалением, если изменить настройки terser:
terserOptions: {
format: {
comments: false
}
}
В таком случае баннер будет потерян.
BannerPlugin применяется ко всем выходным файлам по умолчанию.
Если требуется ограничение по условиям, используется проверка внутри функции:
new webpack.BannerPlugin({
banner: (data) => {
if (data.chunk.name === 'admin') {
return 'Admin bundle';
}
return 'Public bundle';
}
})
Это позволяет разделять метки для разных частей приложения.
В системах непрерывной интеграции BannerPlugin часто используется для маркировки сборок:
new webpack.BannerPlugin({
banner: () => {
return [
`Commit: ${process.env.GIT_COMMIT}`,
`Build number: ${process.env.BUILD_ID}`,
`Branch: ${process.env.GIT_BRANCH}`
].join('\n');
}
})
Такая схема позволяет отслеживать происхождение артефактов без внешних метаданных.
Несмотря на простоту, плагин имеет ряд особенностей:
Из-за этого BannerPlugin не подходит для трансформации логики приложения.
В проектах с несколькими entry points баннер часто используется для различения бандлов:
new webpack.BannerPlugin({
banner: (data) => {
return `Chunk: ${data.chunk.name}`;
}
})
В результате каждый файл получает собственный идентификатор, что упрощает отладку в продакшене.
BannerPlugin корректно работает совместно с:
Однако порядок подключения влияет на итоговый результат. BannerPlugin должен применяться после генерации чанков, что обеспечивается внутренним lifecycle Webpack.
В случае конфликтов с другими плагинами, модифицирующими source assets, баннер может быть перезаписан или удалён, если другой плагин выполняет полную замену содержимого файла.