О мудаках на примере Angular 19, Saas и Webpack
Или как починить 'verbose logging' в современном проекте не привлекая внимания санитаров.
Суть
Обновляя один из наших проектов на Angular на его последнюю версию (19) на момент написания статьи, заметили что консоль засирается вот такими апокалиптическими сообщениями:
Показываю на тестовом проекте, на реальном эта простыня в несколько мегабайт текста засирала логи как на CI-сервере так и локально до полной невозможности прокрутить вверх, даже с увеличенным буфером в консоли.
Проследовав по ссылке в сообщении, обнаруживаем идейных п#дорасов, решивших что их мнение единственно верное, поэтому все остальные варианты использования стоит ограничить насильно:
@import
is now deprecated as of Dart Sass 1.80.0. Additionally, we’re also deprecating the global versions of Sass built-in functions that are available insass:
modules.
Суть в том что больше никаких глобальных переменных не будет, будут революционные префиксы:
@use "../theme"; button { color: theme.$text-color; background-color: theme.$background-color; }
Накал п#здеца и масштаб работ, которые надо провести в реальном проекте для миграции на такую шизу думаю представить несложно — уйдут месяцы кропотливой работы.
Покажу на небольшом примере что все это означает:
@import 'bootswatch/dist/litera/variables'; // Override Bootstrap variables @import 'bootstrap-variables'; // Import Bootstrap source files from node_modules @import 'bootstrap/scss/bootstrap'; //@import 'bootswatch/dist/litera/bootswatch'; @import "~@ng-select/ng-select/themes/default.theme.css"; @import "~quill/dist/quill.core.css"; @import "~quill/dist/quill.snow.css";
Весь этот код, все импорты теперь считаются 'устаревшими' с точки зрения больных у#бков из команды разработки какого-то сраного препроцессора стилей.
Разумеется уже есть готовое решение, выглядит вот так:
@use './config/index.scss' as *;
Дело в том что 90% ругани идет не на собственный код, который еще можно как-то поправить, а на стили из Bootstrap, которые разумеется никто за вас обновлять не будет.
Вернее уже обновили, но в следующей 6й версии, которая пока не выпущена:
Как несложно догадаться, процесс миграции работающего проекта на новую версию Bootstrap — еще более адский гемморой, чем история с import в каком-то там препроцессоре стилей.
Так что многие проекты до сих пор используют устаревшие версии Bootstrap: 4ю и даже 3ю.
Поэтому еще долго придется оставаться на текущей 5й версии Bootstrap и видеть эти зло#бучие предупреждения.
С глаз долой
Вообщем решили убрать с глаз долой все эти п#дорские страсти — заглушить предупреждения об устаревании import
, хотя-бы до момента выпуска Bootstrap 6.
Как уже писал выше, наши проекты регулярно обновляются на свежие версии библиотек, в том числе и Angular, по мере выхода новых бюллетеней безопасности.
В этот раз обновляли на Angular 19, где и вылезла вся эта порнографическая история:
After some research, I found that the issue is due to the Angular Sass compiler dependency being updated from version "1.77.6" to "1.80.6".
И казалось бы авторы Angular недаром работают в Google и заранее подумали о простых разработчиках:
Through some investigation and a helpful tip from ma man Matthieu Riegler, I learned that Angular v19 release candidate already ships an option in the Sass (pre-)compiler settings configuration to address this exact problem.
Согласно официальному руководству, все что надо для отключения назойливых сообщений об устаревании — добавить в angular.json
такую настройку:
.. "architect": { "build": { "options": { "stylePreprocessorOptions": { "sass": { "silenceDeprecations": ["mixed-decls", "color-functions", "global-builtin", "import"] } } } } }, ..
Но к сожалению есть один важный нюанс, о котором разработчики Angular решили скромно умолчать:
Cтарые и сложные проекты обычно используют custom-webpack со своей настройкой Webpack:
Конечно пользователи попросили добавить этот костыль и в куда чаще используемый build-angular:browser
, на что лаконично были посланы нахер:
Перепиливать рабочий проект на использование application-builder — еще более п#зданутая затея, чем миграция на последний Bootstrap ради импортов препроцессора.
Это вообще врядли возможно технически, поскольку в кастомизированном Webpack например находится настройка BrowserSync
:
.. if (targetOptions.target === 'serve' || config.watch) { config.plugins.push( new BrowserSyncPlugin( { host: 'localhost', port: 9000, https: false, open: false, // Disable UI completely ui: false, proxy: { target: `http://localhost:${targetOptions.target === 'serve' ? '4200' : '8080'}`, ws: true, proxyOptions: { changeOrigin: false, //pass the Host header to the backend unchanged https://github.com/Browsersync/browser-sync/issues/430 }, }, socket: { clients: { heartbeatTimeout: 60000, }, }, ..
И хера с два получится просто и быстро от всего этого отказаться.
Решение
Так что, получается калифорнийские п#доры и зверо#бы победили и решения нет?
Остается только уныло листать потоки исторгаемого бессмысленного говна и постоянно чистить сборки на CI-сервере?
На ваше и наших заказчиков счастье, автор получал инженерный диплом не по блату и учили его настоящие советские инженеры, поэтому все что ездит, плавает и летает компьютеры и технологии делают то что надо нам, а не каким-то заморским п#дорасам.
Решение нашлось, хотя и пришлось покопаться в исходниках Angular, модулей сборки, Webpack — короче везде и всюду залезть руками.
Выглядит решение так (код добавляется в кастомный Webpack-скрипт):
.. module.exports = async (config, options, targetOptions) => { .. config.module.rules.push({ test: /\.scss$|\.sass$/, use: [ { loader: require.resolve('sass-loader'), options: { sassOptions: { quietDeps: true, silenceDeprecations: ['mixed-decls', 'color-functions', 'global-builtin', 'import'], }, }, }, ], }); ..
Это уникальное решение, в других местах вы его не найдете.
Сладкое
На сладкое расскажу про настройку уровня логирования в самом Webpack, который тоже успел за#бать своей статистикой сборки по каждому файлу.
Точно также через кастомный Webpack добавляется вот такая настройка:
.. module.exports = async (config, options, targetOptions) => { .. config.infrastructureLogging = { level: 'error', }; ..
Целиком такую связку из Angular+Webpack можно посмотреть например в тестовом проекте JHipster вот тут.
И да, это тоже нигде не описано и готового решения в сети вы не найдете, нам же пришлось лезть внутрь самого Webpack.