JavaScript. Импорт и экспорт
07.03.2021
Теги: export • Frontend • JavaScript • Web-разработка • Модуль • Теория
Экспорт
Можно пометить любое объявление переменной, функция или класса как экспортируемое, разместив перед ним ключевое слово export
:
// экспорт массива export let numbers = [1, 2, 3]; // экспорт константы export const SOME_CONST = 2015; // экспорт класса export class User { constructor(name) { this.name = name; } }
Также можно написать export
отдельно — сначала объявить, а затем экспортировать:
/* * файл say.js */ function sayHi(user) { alert(`Hello, ${user}!`); } function sayBye(user) { alert(`Bye, ${user}!`); } // список экспортируемых переменных export {sayHi, sayBye};
Импорт
Обычно список того, что нужно импортировать, размещается в фигурных скобках {...}
, например вот так:
/* * файл main.js */ import {sayHi, sayBye} from './say.js'; sayHi('John'); // Hello, John! sayBye('John'); // Bye, John!
Но если импортировать нужно много чего — можно импортировать всё сразу в виде объекта:
/* * файл main.js */ import * as say from './say.js'; say.sayHi('John'); say.sayBye('John');
На первый взгляд «импортировать всё» выглядит очень удобно, не надо писать лишнего, зачем нам вообще может понадобиться явно перечислять список того, что нужно импортировать? Современные инструменты сборки (webpack и другие) собирают модули вместе и оптимизируют их, ускоряя загрузку и удаляя неиспользуемый код. Предположим, мы добавили в наш проект стороннюю библиотеку say.js
с множеством функций:
/* * файл say.js */ export function sayHi() { ... } export function sayBye() { ... } export function doSomething() { ... }
Теперь, если из этой библиотеки в проекте мы используем только одну функцию:
/* * файл main.js */ import {sayHi} from './say.js';
…Тогда оптимизатор увидит, что другие функции не используются, и удалит остальные из собранного кода.
Импорт и экспорт «как»
Можно использовать ключевое слово as
, чтобы импортировать под другими именами:
/* * файл main.js */ import {sayHi as hi, sayBye as bye} from './say.js'; hi('John'); // Hello, John! bye('John'); // Bye, John!
Аналогичный синтаксис существует и для export
:
/* * файл say.js */ function sayHi() { ... } function sayBye() { ... } export {sayHi as hi, sayBye as bye};
/* * файл main.js */ import * as say from './say.js'; say.hi('John'); // Hello, John! say.bye('John'); // Bye, John!
Экспорт по умолчанию
На практике модули встречаются в основном одного из двух типов:
- Модуль, содержащий библиотеку или набор функций, как
say.js
в примерах выше - Модуль, который объявляет что-то одно, например модуль
user.js
экспортирует только классUser
По большей части, удобнее второй подход, когда каждая «вещь» находится в своём собственном модуле. Для этого случая есть специальный синтаксис «экспорт по умолчанию»:
/* * файл user.js */ export default class User { // просто добавляем default constructor(name) { this.name = name; } }
И потом импортируем без фигурных скобок:
/* * файл main.js */ import User from './user.js'; // не {User}, а просто User new User('John');
Импорты без фигурных скобок выглядят красивее. Обычная ошибка начинающих: забывать про фигурные скобки. Фигурные скобки необходимы в случае именованных экспортов, для export default
они не нужны.
Так как в файле может быть максимум один export default,
то экспортируемая сущность не обязана иметь имя:
/* * файл user.js */ export default class { // у класса нет имени constructor() { this.name = name; } }
Это нормально, потому что может быть только один export default
на файл, так что import
знает, что импортировать:
/* * файл main.js */ import User from './user.js'; new User('John');
Имя «default»
В некоторых ситуациях для обозначения экспорта по умолчанию в качестве имени используется default
:
/* * файл user.js */ class User { constructor(name) { this.name = name; } } // то же самое, как если добавить export default перед class export {User as default};
/* * файл main.js */ import User from './user.js'; new User('John');
Представим еще одну ситуацию — модуль user.js
экспортирует одну сущность «по умолчанию» и несколько именованных:
/* * файл user.js */ export default class User { constructor(name) { this.name = name; } } export function sayHi(user) { alert(`Hello, ${user}!`); }
Вот как импортировать экспорт по умолчанию вместе с именованным экспортом:
/* * файл main.js */ import {default as User, sayHi} from './user.js'; new User('John');
Если импортировать всё как объект *
, тогда свойство default
— как раз и будет экспортом по умолчанию:
/* * файл main.js */ import * as user from './user.js'; let User = user.default; // экспорт по умолчанию new User('John');
Поиск: export • import • JavaScript • Web-разработка • экспорт • импорт • Теория • Frontend