Tree shaking - видалення з продакшен-збірки коду, який експортується, але ніде не імпортується. Назва - від образу «струсити дерево залежностей, щоб сухе листя впало».
// utils.js
export function formatPrice() { /* ... */ }
export function parseCsv() { /* 20 КБ коду */ }
// app.js
import { formatPrice } from './utils.js';
У зібраному файлі parseCsv не буде.
Чому це можливо лише з ES-модулями: статичні import/export відомі до виконання - збирач будує граф і бачить, що використовується. require() можна викликати динамічно, з обчисленим шляхом, а module.exports змінювати як завгодно - для CommonJS надійно визначити невикористаний код неможливо.
Чому невикористаний код лишається:
1. Побічні ефекти модуля. Якщо модуль при імпорті щось робить (змінює глобальні об'єкти, реєструє компоненти, додає стилі), збирач не може його викинути, навіть якщо експорти не використовуються:
// side-effects.js
window.analytics = createTracker(); // виконується при імпорті
export const unused = 1;
Пакет може оголосити, що його модулі побічних ефектів не мають: "sideEffects": false у package.json (або список файлів з ефектами - наприклад, CSS).
2. Імпорт «всього». import _ from 'lodash' і виклик _.debounce - збирач не знає, які методи об'єкта будуть потрібні. Краще import { debounce } from 'lodash-es' - пакет у форматі ES-модулів з окремими експортами.
3. Пакет у форматі CommonJS. Більшість збирачів обробляють його як єдине ціле.
4. Класи й об'єкти. Метод класу, який ніхто не викликає, не видаляється: збирач видаляє експорти, а не невикористані частини об'єктів.
5. Виклики на верхньому рівні, результат яких не використовується, але які можуть мати ефект: export const config = createConfig(). Позначка /* @__PURE__ */ перед викликом каже збирачу, що виклик чистий і його можна видалити, якщо результат не потрібен.
Як перевірити, що потрапило в бандл: rollup-plugin-visualizer для Vite показує розмір кожного модуля у збірці. Часто виявляється, що одна іконка тягне всю бібліотеку іконок або ціла локалізація моментів дат потрапила через один імпорт.
Tree shaking працює лише в продакшен-збірці. У режимі розробки Vite віддає модулі як є - розмір там не показовий.