Найти в Дзене

Как ускорить Webpack сборку проекта на Typescript с 42 до 16 секунд

При переходе на очередной проект, столкнулся с тем, что его локальный запуск происходит не быстро. Репозиторий не сказать бы что большой, поэтому 42 секунды (mac air m1 2020) для него многовато. Итак, вот один из примеров, что можно попробовать сделать в подобном случае: Для начала, нужно понять на что именно уходит это время. Для любого инструмента сборки есть или встроенные средства, или стороннее расширение. В нашем случае, это speed-measure-webpack-plugin. Устанавливаем, оборачиваем им наш конфиг сборки, запускаем и видим следующее: General output time took 42.15 secs
eslint-webpack-plugin took 21.59 secs
awesome-typescript-loader took 12.51 secs На самом деле список результатов длиннее, но я показываю лишь то, что нам сейчас интересно. Итак, половина времени уходит на ESLint проверки, ну и наш typescript код собирается не сказать бы что быстро. Первым делом идём за описанием настроек eslint-webpack-plugin и ищем параметры которые помогут сократить время проверки. threads: true - к

При переходе на очередной проект, столкнулся с тем, что его локальный запуск происходит не быстро. Репозиторий не сказать бы что большой, поэтому 42 секунды (mac air m1 2020) для него многовато. Итак, вот один из примеров, что можно попробовать сделать в подобном случае:

Для начала, нужно понять на что именно уходит это время. Для любого инструмента сборки есть или встроенные средства, или стороннее расширение. В нашем случае, это speed-measure-webpack-plugin. Устанавливаем, оборачиваем им наш конфиг сборки, запускаем и видим следующее:

General output time took 42.15 secs
eslint-webpack-plugin took 21.59 secs
awesome-typescript-loader took 12.51 secs

На самом деле список результатов длиннее, но я показываю лишь то, что нам сейчас интересно.

Итак, половина времени уходит на ESLint проверки, ну и наш typescript код собирается не сказать бы что быстро.

Первым делом идём за описанием настроек eslint-webpack-plugin и ищем параметры которые помогут сократить время проверки. threads: true - кажется то что нужно, и оно действительно ускоряет проверку в разы, но вот незадача, ошибки и предупреждения перестают выводиться в консоль. Ковыряния в issues приводит к тому что это баг и похоже его ни кто не собирается чинить. Попутно находится issue, в котором пишут что скорость eslint-webpack-plugin оставляет желать лучшего, и с этим тоже ни чего особого не делают.

Пока отложим этот вопрос и перейдём к сборке typescript кода.

Идём в описание awesome-typescript-loader и видим раздел performance issues, читам, понимаем что в нашем случае всё уже сделано. Остаётся последовать совету, и попробовать ts-loader. Заменяем awesome-typescript-loader на ts-loader и видим следующее:

ts-loader took 12.17 secs

На первый взгляд, кажется что мы поменяли шило на мыло, но не расстраиваемся и идём в раздел документации faster builds и пробуем что там написано. В итоге приходим к следующему:

loader: 'ts-loader',
options: {
transpileOnly: true,
onlyCompileBundledFiles: true,
}

Плюс, устанавливаем и настраиваем fork-ts-checker-webpack-plugin, что в итоге даёт нам следующее:

fork-ts-checker-webpack-plugin took 0.002 secs
ts-loader took 8.3 secs // <= неплохое улучшение

Если поковырять описание, то находим следующее: ESLint feature, please use version 6 of the plugin. Не смотря на то, что уже есть 8 версия, 6-ю продолжают обновлять (по крайней мере на момент написания этого текста). Разбираемся что за ESLint фича такая, удаляем eslint-webpack-plugin, а вместо него включаем ту самую фичу:

new ForkTsCheckerWebpackPlugin({
eslint: {
// Тут желательно использовать переменную,
// что бы true был только при локальной разработке
enabled: true,
// Файлы, которые необходимо проверять
files: './src/**/*.{ts,tsx}',
},
}),

В итоге мы получаем следующее:

General output time took 15.77 secs
fork-ts-checker-webpack-plugin took 0.002 secs
ts-loader took 8.3 secs

Судя по времени выполнения, кажется что fork-ts-checker-webpack-plugin делает все проверки асинхронно, что позволяет стартануть проект очень быстро.

Кстати, по умолчанию, все ESLint ошибки и предупреждения сыпятся не только в системную консоль (где выполняли команду запуска), но и в консоль браузера.

На самом деле сборку можно было бы ещё ускорить до ~10 сек, заменив ts-loader на esbuild-loader (который к тому же поддерживает минификацию и css), но конкретно в моём случае пока что нужно сохранить сборку в target es5.

Больше информации в Telegram канале https://t.me/around_dev