Іменований експорт - модуль може мати їх скільки завгодно, імпортують їх за точною назвою у фігурних дужках:
// validation.js
export function isEmail(value) { /* ... */ }
export const MAX_LENGTH = 255;
// інший файл
import { isEmail, MAX_LENGTH } from './validation.js';
import { isEmail as checkEmail } from './validation.js'; // перейменування
import * as validation from './validation.js'; // усе як об'єкт-простір імен
Експорт за замовчуванням - один на модуль, імпортується без дужок і під будь-якою назвою:
// Modal.vue, api.js
export default function createApi(baseUrl) { /* ... */ }
import createApi from './api.js';
import makeClient from './api.js'; // теж працює - та сама функція
Модуль може мати й те, й інше: import axios, { AxiosError } from 'axios'.
Аргументи на користь іменованих експортів:
- однакові назви всюди: не буває ситуації, коли в одному файлі функцію імпортували як
createApi, в іншому якapiFactory, - пошук і рефакторинг простіші; - помилка в назві помітна одразу:
import { isEmial }- збирач чи редактор скаже, що такого експорту немає. З експортом за замовчуванням будь-яка назва «правильна»; - автоімпорт у редакторі працює точніше;
- tree shaking простіше розібратися з окремими експортами, ніж з одним великим об'єктом за замовчуванням.
Через це багато команд мають правило лінтера «лише іменовані експорти» (import/no-default-export).
Коли експорт за замовчуванням природний:
- файл = одна сутність: компонент Vue (
.vue-файли експортують компонент за замовчуванням), сторінка в Next.js, конфіг (vite.config.js-export default defineConfig(...)); - вимога інструмента, що шукає саме
default.
Реекспорт - для «бочок» (index.js, що збирає експорти папки):
export { isEmail, MAX_LENGTH } from './validation.js';
export { default as Modal } from './Modal.vue';
export * from './formatters.js';
Великі «бочки» мають ціну: імпорт однієї функції з index.js змушує збирач обробити всі реекспортовані модулі, а в режимі розробки - ще й завантажити їх.