Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке tree shaking і чому він інколи не прибирає невикористаний код?

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 віддає модулі як є - розмір там не показовий.

Докладніше в документації: Tree shaking

Схожі питання