webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
JavaScript · Урок 16 из 17

Модули: import / export

Named или default, динамический импорт, tree shaking и barrel-файлы.

Обновлено

Что такое модуль

Модуль — файл JS со своей областью видимости: переменные и функции в нём приватны, пока вы явно их не экспортируете. Другой файл использует их через import.

Зачем: без модулей весь код жил бы в одном глобальном пространстве — конфликты имён, скрытые зависимости, поддерживать невозможно. С модулями каждый файл ясно объявляет, что он даёт и что ему нужно.

// math.js
const secret = 42                         // приватно — не экспортировано
export const sum = (a, b) => a + b        // публично

// app.js
import { sum } from './math.js'
sum(1, 2)

Виды экспорта

Вид Синтаксис экспорта Синтаксис импорта Сколько в файле
named export const sum = ... import { sum } from './math' сколько угодно
default export default function Page() {} import Page from './page' (любое имя) один
реэкспорт export { sum } from './math' — —
import multiply, { sum, avg as average } from './math.js'  // default + named + переименование
import * as math from './math.js'                           // всё сразу, как объект

Named или default — когда

Named Default
Имя при импорте фиксированное — везде одинаковое выбираете сами — может отличаться в каждом файле
Рефакторинг, автодополнение, поиск лучше хуже
Где обязателен — page.tsx, layout.tsx, next.config.ts в Next

Рекомендация: named-экспорты для всего своего кода; default — только там, где требует фреймворк.

Статический и динамический импорт

import x from (статический) await import() (динамический)
Когда загружается при старте, до выполнения кода по требованию, когда дойдёте до этой строки
Где только вверху файла где угодно (в функциях, условиях)
Для почти всего тяжёлого редко используемого кода: редакторы, графики, карты
button.onclick = async () => {
  const { Chart } = await import('./chart.js')   // скачивается только по клику
}

В Next: next/dynamic делает то же для компонентов — именно так загружается редактор кода в этом приложении.

Tree shaking

Tree shaking = сборщик удаляет из бандла экспорты, которые никто не импортирует. Работает только со статическими import/export.

import { debounce } from 'lodash-es'   // ✓ в бандл попадёт только debounce
import _ from 'lodash'                 // ✗ в бандл попадёт вся библиотека

Barrel-файлы

Barrel — это index.ts, который только реэкспортирует другие файлы (export * from './a'). Кажется удобным, но:

  • импорт одной вещи загружает всё, что реэкспортирует barrel;
  • замедляет dev-сервер и тесты;
  • легко создаёт циклические импорты.

В нашем проекте мы импортируем напрямую из файла — см. Feature-Sliced Design.

ESM и CommonJS

ES Modules (ESM) CommonJS (CJS)
Синтаксис import / export require() / module.exports
Где браузер, Next, современный Node старый Node, некоторые библиотеки
Статичность (tree shaking) да нет

Пишете на ESM. CJS встретите только в старых конфигурациях.

Коротко

  • Модуль = файл со своей областью видимости; экспортируете то, что публично.
  • Named-экспорты по умолчанию; default — только где требуется.
  • Динамический импорт для тяжёлого кода; tree shaking — только со статическими импортами; избегайте barrel-файлов.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.