Именованные и default-экспорты

Именованные и default-экспорты

Технический фундамент типов экспорта

При проектировании API модуля полезно держать такие правила:

  • именованные экспорты лучше подходят для стабильных утилитных наборов;
  • default лучше подходит для одной "главной" сущности файла;
  • переименование default-импорта гибкое, но может ухудшать единообразие кодовой базы;
  • чем явнее контракт экспорта, тем безопаснее массовый рефакторинг.

Практический инженерный ориентир: делай публичное API модуля предсказуемым, а не "удобным в одном месте".

Почему важно понимать разницу

В JavaScript есть два основных способа экспортировать сущности из модуля: именованный (named export) и экспорт по умолчанию (default export). Если путать их, получаешь ошибки импорта и нестабильную структуру проекта.

Ключевой момент: именованный экспорт привязан к конкретному имени, а default - к "главной сущности" модуля без обязательного имени на стороне импорта.

Проверь себя: когда в модуле логично выбрать default, а когда именованные экспорты?

Именованные экспорты

Именованные экспорты позволяют отдать несколько сущностей из одного файла.

// formatter.js
export function formatPrice(value) {
  return `${value} ₽`;
}

export function formatDate(date) {
  return date.toISOString();
}

Импортируются они строго по именам в фигурных скобках.

import { formatPrice, formatDate } from './formatter.js';

Смотри, что важно: можно импортировать только нужное, это повышает читаемость и делает зависимости явными.

default export

Default export обычно используют, когда в модуле есть одна ключевая сущность.

// taxCalculator.js
export default function calculateTax(amount) {
  return amount * 0.2;
}

Импорт без фигурных скобок:

import calculateTax from './taxCalculator.js';

Здесь часто путаются: имя calculateTax на стороне импорта можно выбрать другое.

import taxFn from './taxCalculator.js';

Это работает, но не всегда полезно для читаемости. Лучше сохранять осмысленные имена.

Комбинация default и именованных

В одном модуле можно иметь один default и несколько именованных экспортов.

// userService.js
export default function getUserName(user) {
  return user.name;
}

export const ROLE_ADMIN = 'admin';
export function isAdmin(user) {
  return user.role === ROLE_ADMIN;
}

Импорт:

import getUserName, { ROLE_ADMIN, isAdmin } from './userService.js';

Проверь себя: почему default всегда только один в файле?

Как выбирать между подходами

Ориентир:

  • если модуль отдает одну главную сущность -> default;
  • если модуль отдает набор утилит -> именованные экспорты;
  • если структура смешанная, используй комбинацию осознанно.

В продуктовой разработке команды часто предпочитают именованные экспорты для большей явности и более безопасного рефакторинга.

Типичные ошибки новичков

  • Импортировать default в фигурных скобках.
  • Пытаться импортировать именованный экспорт без скобок.
  • Создавать несколько default в одном модуле.
  • Давать default-импорту неочевидные имена и путать коллег.
// Ошибка: default импорт не через {}
import { calculateTax } from './taxCalculator.js';

Дополнительный пример: реэкспорт default под именем для унифицированного API.

// calculators/index.js
export { default as calculateTax } from './taxCalculator.js';

// app.js
import { calculateTax } from './calculators/index.js';
console.log(calculateTax(500));

Так можно выровнять стиль импортов в проекте: снаружи все выглядит как named API, даже если внутри часть модулей использует default.

Анти-провал: перед импортом проверяй, как именно модуль экспортирует сущность: export ... или export default ....

Микро-сценарии

  1. default для React-компонента страницы.

Модуль экспортирует один главный компонент экрана, поэтому default читается естественно.

  1. Именованные экспорты для утилит даты и валюты.

Ты импортируешь только нужные функции и избегаешь "черного ящика".

Что будет, если изменить входные данные

В calculateTax(1000) результат 200. Если передать null без проверки, логика может сломаться или вернуть неожиданный результат. Поэтому даже при правильных export/import важно держать контракт данных понятным.

Проверь себя: влияет ли тип экспорта (default/именованный) на необходимость валидации входа функции?

Краткий итог

  • Именованные экспорты привязаны к именам и импортируются через {}.
  • Default export предназначен для главной сущности модуля и импортируется без {}.
  • В модуле может быть только один default, но много именованных экспортов.
  • Выбор типа экспорта влияет на читаемость и удобство поддержки.
  • Большинство ошибок в этой теме связаны с перепутанным синтаксисом импорта.