Структурируй проекты с помощью ES-модулей, используя их статический анализ и избегая токсичных бочек и циклических зависимостей.
Открыть этот урок в KodokonES-модули статичны: инструкции import и export разрешаются при разборе файла, ещё до запуска кода. Именно это делает возможным tree-shaking (удаление кода, который никогда не импортируется) и отлов ошибок в именах на этапе сборки. Именованные экспорты или экспорт по умолчанию? Именованные выигрывают почти по всем фронтам: удобное переименование при рефакторинге, надёжное автодополнение и никакой возможности импортировать одно и то же под десятью разными именами. Прибереги default для случая, когда модуль экспортирует одну очевидную вещь.
export const TAX_RATE = 0.2;
export function applyTax(price) {
return price * (1 + TAX_RATE);
}
export default class Cart {
items = [];
add(item) {
this.items.push(item);
return this;
}
}На стороне потребителя четыре формы: именованный импорт (с необязательным псевдонимом через as), импорт по умолчанию, импорт пространства имён (* as) и динамический импорт import(), который возвращает промис с пространством имён. Последний - строительный блок разделения кода: тяжёлый модуль (редактор, график, PDF) загружается только в тот момент, когда он реально нужен пользователю.
import Cart, { applyTax, TAX_RATE } from "./cart.js";
import * as cartModule from "./cart.js";
console.log(applyTax(100), TAX_RATE); // 120 0.2
console.log(cartModule.TAX_RATE); // 0.2
const lazy = await import("./cart.js");
const cart = new lazy.default();
console.log(cart instanceof Cart); // trueДля организации предпочитай деление по функциональности (features/cart/, features/auth/), а не по техническому типу (controllers/, helpers/): код, который меняется вместе, лежит вместе, и удалить функциональность - это удалить одну папку. Открывай каждую функциональность через узкую точку входа и считай любой импорт в обход этой точки нарушением границы.
import("./module.js")?