export и import

export и import #

export публикует привязки (переменные, функции, классы) из модуля. import подключает их в другой файл. Связь статическая: анализатор знает зависимости до выполнения кода.


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

Несколько сущностей из одного файла — каждая со своим именем:

// pricing.js
export const currency = 'RUB'

export function formatMoney(amount) {
  return `${amount.toFixed(2)} ${currency}`
}

export class PriceError extends Error {
  constructor(message) {
    super(message)
    this.name = 'PriceError'
  }
}

Импорт с теми же именами или с переименованием:

import { currency, formatMoney } from './pricing.js'
import { formatMoney as fmt } from './pricing.js'

fmt(1990) // "1990.00 RUB"

Фигурные скобки обязательны для именованного импорта — это не деструктуризация объекта, а статический список привязок модуля.


Экспорт после объявления #

function buildSku(prefix, id) {
  return `${prefix}-${id}`
}

const defaultPrefix = 'JSF'

export { buildSku, defaultPrefix }

Можно экспортировать под другим именем:

export { buildSku as makeSku }

Default export #

Один «главный» экспорт на файл — удобно для компонента или класса точки входа:

// playlist-store.js
export default class PlaylistStore {
  constructor() {
    this.tracks = []
  }

  add(track) {
    this.tracks.push(track)
  }
}

Импорт без фигурных скобок; имя локальное:

import Playlist from './playlist-store.js'
import MyStore from './playlist-store.js' // то же самое, имя свободное

const store = new Playlist()
store.add({ id: 'tr-1', title: 'Harbor Light' })

В одном файле может быть один default и любое число именованных экспортов.

import Playlist, { /* нет именованных в этом примере */ } from './playlist-store.js'

Импорт только ради побочного эффекта #

import './telemetry/setup.js'

Файл выполнится один раз (регистрация слушателей, полифилл) без привязки к переменной.


Импорт всего модуля как объекта #

import * as pricing from './pricing.js'

pricing.formatMoney(500)
pricing.currency

Пространство имён не включает default как свойство автоматически — для default нужен отдельный импорт или import mod, * as ns.


Реэкспорт #

Сборка публичного API пакета из внутренних файлов:

// checkout/index.js
export { formatMoney, currency } from './pricing.js'
export { default as PlaylistStore } from '../playlist-store.js'

Потребитель импортирует из одной «витрины»:

import { formatMoney, PlaylistStore } from './checkout/index.js'

export * from './utils.js' реэкспортирует все именованные привязки, кроме default (для default — явная форма).


Ограничения путей #

В браузере:

import { x } from './lib/math.js' // OK — относительный путь
import { x } from '/abs/path/math.js' // OK — от корня сайта
import { x } from 'math' // ошибка без import map / бандлера

Расширение .js в пути обычно указывают явно в нативных ESM-браузерах.


Итог #

  • Именованный export / import { } — несколько API из файла.
  • export default / import Name — один основной экспорт, имя при импорте произвольное.
  • import * as ns — пространство имён; реэкспорт собирает публичную поверхность модуля.
  • Пути должны быть относительными или полными URL в браузере без сборщика.

См. также #