Импорт и экспорт функций в JavaScript

JavaScript сейчас отвечает за большую часть интерактивности на веб‑страницах. Фронтенд‑разработчики используют его для приложений, виджетов и библиотек. С развитием языка появились стандартные способы делиться кодом между файлами — модули. Эта статья подробно объяснит, как экспортировать и импортировать функции, какие приёмы и подводные камни есть, а также даст практические советы и шаблоны.
Что такое JavaScript‑модуль?
Определение: модуль — это отдельный файл JavaScript, который экспортирует функции, объекты или данные для использования в других файлах.
Модули упрощают организацию кода. Вы пишете утилиту в одном файле и подключаете её там, где нужно. В браузере модуль подключают через атрибут type=”module”:
Типы модулей, с которыми вы можете столкнуться:
- ECMAScript modules (ESM) — современный стандарт, поддерживается в браузерах и в новых версиях Node.js.
- CommonJS (CJS) — старый формат модулей, широко использовался в Node.js и пакетах до массового перехода на ESM.
Ниже мы сосредоточимся на ECMAScript модулях. Если вы работаете в старом окружении, рассмотрите инструкцию по миграции в раздел «Миграция и совместимость».
Как экспортировать функции в JavaScript
Экспорт функции делает её доступной из других файлов. В JavaScript есть два основных способа экспортировать:
- Именованный экспорт (named export)
- Экспорт по умолчанию (default export)
Пример функции, которая запрашивает имя у пользователя и возвращает его (простая демонстрация):
function getFullName() {
const fullName = prompt('What is your First Name');
console.log(fullName);
return fullName;
}Именованный экспорт — вы экспортируете одну или несколько сущностей по имени:
// В конце файла
export { getFullName };
// Или при объявлении
export function getFullName() {
const fullName = prompt('What is your First Name');
console.log(fullName);
return fullName;
}Если нужно экспортировать сразу несколько функций:
export { getFullName, getEmail, getDob };Экспорт по умолчанию используют, когда модуль предоставляет одну основную сущность или удобен fallback:
export default function getFullName() {
const fullName = prompt('What is your First Name');
return fullName;
}Важно: в модуле может быть только один export default.
Как импортировать функции в JavaScript
Импорт делает экспортированные сущности доступными в другом файле. Базовые формы:
Именованный импорт одной функции:
import { getFullName } from './getPersonalDetails.js';Импорт нескольких именованных экспортов:
import { getFullName, getEmail, getDob } from './getPersonalDetails.js';Импорт всех экспортов как объекта:
import * as personalDetailsModule from './getPersonalDetails.js';
personalDetailsModule.getFullName();Импорт значения по умолчанию:
import fullName from './getPersonalDetails.js';
// если модуль экспортировал default функцию, её можно вызвать так:
fullName();Псевдонимы и переименование:
import { getFullName as nameFetcher } from './getPersonalDetails.js';
nameFetcher();Динамический импорт (рантайм, возвращает Promise):
// используется, когда нужно подгружать модуль по условию или лениво
const module = await import('./heavyModule.js');
module.doHeavyWork();Динамический импорт полезен для ленивой загрузки и разделения кода.
Различия между именованными и default экспортами
- Именованный экспорт требует точного имени и фигурных скобок при импорте.
- Default импорт не использует фигурные скобки и даёт возможность выбрать локальное имя.
- Именованных экспортов может быть несколько. Default — только один.
Практическое правило: если файл экспортирует набор утилит — используйте именованные экспорты. Если модуль представляет одну главную сущность (класс, функцию-обёртку) — используйте export default.
Частые ошибки и почему импорт/экспорт не работает
- Забыл указать type=”module” в браузере. Тогда import/ export вызовет синтаксическую ошибку.
- Неверный путь или опечатка в имени файла (учтите относительные ./ и ../).
- Отсутствует расширение в окружении, где браузер требует .js (например,
import … from ‘./file’в браузере часто нужно указывать ‘./file.js’). - Смешение CommonJS и ESM без корректной конфигурации (в Node.js нужно указывать “type”: “module” в package.json или использовать .mjs).
- Циклические зависимости: два модуля импортируют друг друга. Это работает не всегда ожидаемым образом и может вернуть неопределённые значения на этапе инициализации.
- Попытка экспортировать несколько default в одном файле.
Важно: ошибки обычно проявляются в консоли — внимательно читайте сообщения об ошибках и стек трейс.
Миграция и совместимость
Советы для проектов на Node.js:
- Для перехода на ESM добавьте в package.json: “type”: “module”. Это включит поддержку import/export для файлов .js.
- Альтернатива — переименовать файлы в .mjs.
- Если вы используете зависимости, написанные под CommonJS, проверьте, как они импортируются в ESM (иногда нужно использовать default import или импорт через createRequire).
Советы для браузера:
- Современные браузеры поддерживают ESM. Для старых нужно использовать сборщик (Webpack, Rollup, Parcel) и транспилирование.
- При разработке учитывайте поддержку модулей в целевых браузерах.
Руководство по лучшим практикам
- Разделяйте код по ответственности: один модуль — одна область ответственности.
- Экспортируйте минимально необходимое API. Скрывайте вспомогательные функции.
- Используйте именованные экспорты для утилит; default — для главной сущности.
- Держите относительные пути короткими, а индексные файлы (index.js) используйте для агрегирования экспортов.
- Пишите тесты на экспортируемые функции.
Краткий чеклист перед публикацией модуля:
- Все экспортируемые функции задокументированы.
- Нет глобальных побочных эффектов при импорте.
- Имена экспортов стабильны и понятны.
- Циклических зависимостей минимум.
Полезные шаблоны и шпаргалка
Шпаргалка по синтаксису:
// именованные экспорты
export function a() {}
export const b = 1;
export { a, b };
// экспорт по умолчанию
export default function main() {}
// импорт
import { a, b } from './lib.js';
import main from './main.js';
import * as lib from './lib.js';
// псевдонимы
import { a as fetchA } from './lib.js';
// динамический импорт
import('./optional.js').then(mod => mod.doSomething());Миграция CommonJS -> ESM (быстрая методика):
- Найдите модули с require/module.exports.
- Замените require на import (по возможности). Пример:
- Из: const lib = require(‘./lib’);
- В: import lib from ‘./lib.js’;
- Замените module.exports = x на export default x или export { x }.
- Запустите тесты и исправьте ошибки областей, где смешаны форматы.
Ментальные модели и хинты
- Думайте о модуле как о чёрном ящике: входы — импорт, выходы — экспорт.
- Простая эвристика: «один модуль — одна тема». Если модуль растёт — разбейте его.
- Используйте агрегирующие модули (index.js) для группировки мелких экспортов и упрощения импортов в других частях приложения.
Когда экспорт/импорт неэффективен
- Для одноразовых скриптов, где код не переиспользуется, модули могут добавить лишнюю сложность.
- При очень частых динамических импортах в горячей петле можно получить накладные расходы — профилируйте.
- В окружениях с ограниченными возможностями загрузки (старые браузеры без сборки) лучше использовать один собранный бандл.
Критерии приёмки
- Функции, которые должны быть доступны внешне, экспортируются и документированы.
- Импорты используют корректные относительные или абсолютные пути, которые разрешаются в целевом окружении.
- Никаких ошибок синтаксиса import/export при запуске в целевых браузерах или Node.js.
- Тесты покрывают публичный API модуля.
Быстрый план действий для внедрения модулей в проект
- Выделите служебные утилиты в отдельную папку /src/utils.
- Экспортируйте только публичные функции из index.js в этой папке.
- Обновите импорты по всему проекту, используя именованные экспорты.
- Добавьте lint‑правила, чтобы следить за импортами (ESLint + plugin).
- Пропишите в CI проверку сборки и тестов.
Совместимость и нюансы окружений
- Браузеры: ESM поддерживается в современных браузерах. Для старых используйте сборщик.
- Node.js: начиная с Node 12+ поддержка ESM улучшилась; используйте “type”: “module” или .mjs.
- Пакеты npm: некоторые пакеты предоставляют оба варианта (exports поле в package.json). Проверяйте документацию.
Важно: перед массовой миграцией проверьте совместимость зависимостей и окружения запуска.
Короткое резюме
Модули делают код более организованным и повторно используемым. Выбирайте именованные экспорты для набора утилит и export default для единственной основной сущности. Следите за совместимостью окружения и избегайте циклических зависимостей. Используйте динамический импорт для ленивой загрузки, а индексные файлы — для удобных агрегированных импортов.
Важно: всегда тестируйте изменения API и обновляйте документацию.
Похожие материалы
Специальные символы в Google Sheets: 2 простых способа
Как экономить мобильные данные в Apple Music
Персональные результаты Google Assistant на блокировке
Настройка уведомлений Outlook: отключить и адаптировать
Добавить дату и время в Google Sheets