Что такое tree shaking
Что проверяют
Понимаете ли вы, почему удаление неиспользуемого кода работает только при определённых условиях и что его ломает. Следом обычно просят объяснить поле sideEffects в package.json и рассказать, как вы убедились бы, что лишнее действительно вырезано.
Как отвечать
Tree shaking это удаление из бандла экспортов, которые никто не импортирует. Работает оно благодаря статической структуре ES-модулей: import и export стоят на верхнем уровне и не зависят от выполнения, поэтому сборщик видит граф зависимостей до запуска. С CommonJS так не выйдет: require() можно вызвать в условии, а module.exports собрать динамически.
В инструментах:
- Webpack:
mode: "production"включаетoptimization.usedExports, сборщик помечает неиспользуемые экспорты, а Terser их вырезает. Модуль пропускается целиком, если пакет объявил"sideEffects": false; - Rollup: с него и пошёл термин, удаление встроено в основу. На нём строится продакшен-сборка Vite, в новых версиях на совместимом Rolldown;
- esbuild: удаляет неиспользуемое при сборке с
--bundle.
Ключевое понятие здесь побочные эффекты. Если модуль при импорте что-то делает сам (меняет глобальный объект, ставит полифил, подключает CSS), сборщик не вправе его выбросить. Поле sideEffects сообщает, что таких модулей в пакете нет, или перечисляет их, например ["*.css"]. Аннотация /*#__PURE__*/ перед вызовом разрешает удалить его, если результат не используется.
Результат проверяют анализатором: webpack-bundle-analyzer, rollup-plugin-visualizer или source-map-explorer.
Где спотыкаются
Считают, что tree shaking работает с любой библиотекой. Классика: lodash на CommonJS приезжает целиком, а lodash-es вырезается по функциям.
Ломают его своей конфигурацией. Babel с @babel/preset-env и опцией modules: "commonjs" превращает импорты в require, и сборщику остаётся включить всё. Модули для сборщика нужно оставлять как есть.
Ставят "sideEffects": false в пакете, который импортирует стили, и CSS молча пропадает из сборки. Файлы стилей надо перечислить в массиве исключений.