Экспорт жана импорт директивалары бир нече чалуу варианттарына ээ.
Биз мурунку бөлүмдө жөнөкөй колдонууну көрдүк, эми көбүрөөк мисалдарды карап көрөлү.
Жарыяланганга чейин экспорттоо
Биз каалаган декларацияны export
анын алдына коюу менен, өзгөрмө, функция же класс болобу, аны экспорттоого болот деп белгилей алабыз.
Мисалы, төмөнкү экспорттун бардыгы жарактуу:
@A@// экспорт массива
export let months = ['Jan', 'Feb', 'Mar', 'Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
// экспорт константы
export const MODULES_BECAME_STANDARD_YEAR = 2015;
// экспорт класса
export class User {
constructor(name) {
this.name = name;
}
}@A@
Класс же функциядан мурун аны функция туюнтмасыexport
кылбагандыгын эске алыңыз . Бул экспорттолгонуна карабастан, дагы эле функция декларациясы.
Көпчүлүк JavaScript кодунун стилдик жетектемелери функция же класс декларацияларынан кийин чекиттүү үтүрлөрдү токтотот.
Ошондуктан, аягында чекит керек эмес export class
:export function
@A@export function sayHi(user) {
alert(`Hello, ${user}!`);
} // без ; в конце@A@
Декларациядан өзүнчө экспорттоо
Өзүнчө жазсаңыз да болот export
.
Бул жерде биз адегенде жарыялап, анан экспорттойбуз:
@A@// 📁 say.js
function sayHi(user) {
alert(`Hello, ${user}!`);
}
function sayBye(user) {
alert(`Bye, ${user}!`);
}
export {sayHi, sayBye}; // список экспортируемых переменных@A@
…Же, техникалык жактан биз дагы export
жогорудагы функцияларды жайгаштырсак болот.
Импорт *
Биз көбүнчө тармал кашаага импорттогубуз келген нерселердин тизмесин import {...}
төмөнкүдөй киргизебиз:
@A@// 📁 main.js
import {sayHi, sayBye} from './say.js';
sayHi('John'); // Hello, John!
sayBye('John'); // Bye, John!@A@
Бирок биз көп нерселерди импорттошубуз керек болсо, биз бардыгын бир эле учурда объект катары импорттой алабыз import * as <obj>
. Мисалы:
@A@// 📁 main.js
import * as say from './say.js';
say.sayHi('John');
say.sayBye('John');@A@
Бир караганда, "баарын импорттоо" абдан ыңгайлуу көрүнөт, ашыкча жазуунун кереги жок, эмне үчүн импорттолушу керек болгон нерселердин тизмесин так тизмектешибиз керек?
Мунун бир нече себептери бар.
-
Заманбап куруу куралдары ( вебпакет жана башкалар) модулдарды бириктирип, жүктөөнү тездетүү жана колдонулбаган кодду алып салуу үчүн аларды оптималдаштырат.
Биздин долбоорго көптөгөн функциялары бар үчүнчү тараптын китепканасын коштук дейли
say.js
:@A@// 📁 say.js export function sayHi() { ... } export function sayBye() { ... } export function becomeSilent() { ... }
Эми долбоордо бул китепканадан бир гана функцияны колдонсок:
// 📁 main.js import {sayHi} from './say.js';@A@
...Андан кийин оптимализатор башка функциялар колдонулбай жатканын көрүп, калганын компиляцияланган коддон алып салат, ошону менен кодду кичирейтет. Бул "дарактын титирөө" деп аталат.
-
sayHi()
Импорт кылгыбыз келген нерсени ачык тизмелөө менен, функциянын ордуна кыскараак функция аттарын алабыз:say.sayHi()
. -
Импорттордун ачык тизмеси кодду түшүнүктүү кылат, эмнени жана кайда колдонулганын көрүүгө мүмкүндүк берет. Бул кодду тейлөөнү жана рефакторингди жеңилдетет.
"Кандай" импорттоо
as
Биз башка аталыштар менен импорттоо үчүн да колдоно алабыз .
Мисалы, кыскача айтканда, биз sayHi
жергиликтүү өзгөрмөгө импорттойбуз hi
жана sayBye
төмөнкүдөй импорттойбуз bye
:
@A@// 📁 main.js
import {sayHi as hi, sayBye as bye} from './say.js';
hi('John'); // Hello, John!
bye('John'); // Bye, John!@A@
"катары" экспорттоо
Ошол эле синтаксис үчүн бар export
.
hi
Функцияларды төмөнкүдөй экспорттойлу bye
:
@A@// 📁 say.js
...
export {sayHi as hi, sayBye as bye};@A@
Азыр hi
жана bye
тышкы коддун расмий аталыштары, алар импорттоодо колдонулушу керек:
@A@// 📁 main.js
import * as say from './say.js';
say.hi('John'); // Hello, John!
say.bye('John'); // Bye, John!@A@
Демейки боюнча экспорттоо
Иш жүзүндө модулдар негизинен эки түрдүн биринде кездешет:
- Жогорудагыдай китепкана же функциялар топтомун камтыган модул
say.js
. - Бир нерсени жарыялаган модул, мисалы,
user.js
экспорттогон модулclass User
.
Көпчүлүк учурда, экинчи ыкма ыңгайлуу, ар бир "нерсе" өз модулунда.
Албетте, ар бир нерсе үчүн өзүнчө модуль жасалса, көптөгөн файлдар талап кылынат, бирок бул көйгөй эмес. Бул дагы ыңгайлуу: долбоордун навигациясы жеңилдейт, өзгөчө файлдардын аталыштары жакшы жана папкаларда түзүлсө.
export default
Модулдар экинчи ыкма үчүн атайын синтаксисти ("демейки экспорт") камсыз кылат .
Биз export default
экспорттош керек болгон нерселердин алдына койобуз:
A@// 📁 user.js
export default class User { // просто добавьте "default"
constructor(name) {
this.name = name;
}
}@A@
Файлда эң көп дегенде бирөө болушу мүмкүн экенин эске алыңыз export default
.
...Анан биз тармал кашаасыз импорттойбуз:
@A@// 📁 main.js
import User from './user.js'; // не {User}, просто User
new User('John');@A@
Тармал кашаасыз импорттуктар сулуураак көрүнөт. Баштоочунун кеңири таралган катасы: тармал кашааларды унутуңуз. Эсиңизде болсун: тармал кашаалар аталган экспортто керектелет, export default
алар үчүн кереги жок.
Экспорт деп аталды | Демейки боюнча экспорттоо |
---|---|
export class User {...} |
export default class User {...} |
import {User} from ... |
import User from ... |
Техникалык жактан алганда, бир модул демейки жана аталган экспортко ээ болушу мүмкүн, бирок иш жүзүндө алар адатта аралашпайт. Башкача айтканда, модулда аталган экспорт же бир демейки экспорт бар.
Файлда эң көп дегенде бирөө болушу мүмкүн болгондуктан export default
, экспорттолуучу объекттин аталышы болушу шарт эмес.
Мисалы, булардын бардыгы толук жарактуу демейки экспорт болуп саналат:
@A@export default class { // у класса нет имени
constructor() { ... }
}
export default function(user) { // у функции нет имени
alert(`Hello, ${user}!`);
}
// экспортируем значение, не создавая переменную
export default ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];@A@
Бул жакшы, анткени ар бир файлда бир гана болушу мүмкүн export default
, андыктан import
эч кандай тармал кашаа дайыма эмнени импорттоо керектигин билбейт.
Мындай экспорт болбосо default
, ал ката берет:
@A@export class { // Ошибка! (необходимо имя, если это не экспорт по умолчанию)
constructor() {}
}@A@
Аты "демейки"
Кээ бир учурларда, демейки экспорт аты болуп саналат default
.
Мисалы, функцияны анын декларациясынан өзүнчө экспорттоо үчүн:
@A@function sayHi(user) {
alert(`Hello, ${user}!`);
}
// то же самое, как если бы мы добавили "export default" перед функцией
export {sayHi as default};@A@
Же болбосо, дагы бир жагдайды элестетип көрөлү: модуль user.js
бир объектти "демейки боюнча" жана бир нече аталгандарды экспорттойт (сейрек, бирок мүмкүн болгон учур):
@A@// 📁 user.js
export default class User {
constructor(name) {
this.name = name;
}
}
export function sayHi(user) {
alert(`Hello, ${user}!`);
}@A@
Бул жерде демейки экспортту аталган экспорт менен бирге кантип импорттоо керек:
@A@// 📁 main.js
import {default as User, sayHi} from './user.js';
new User('John');@A@
Жана акырында, эгерде биз бардыгын объект катары импорттосок import *
, анда анын касиети default
демейки экспорт болот:
@A@// 📁 main.js
import * as user from './user.js';
let User = user.default; // экспорт по умолчанию
new User('John');@A@
Демейки экспортко каршы аргумент
Аты аталган экспорт алардын атын "камтыйт". Бул маалымат модулдун бир бөлүгү болуп саналат, бизге экспорттолуп жаткан так айтып берет.
Аты аталган экспорт импорттоодо туура аталышты колдонууга мажбурлайт:
@A@import {User} from './user.js';
// import {MyUser} не сработает, должно быть именно имя {User}@A@
…Демейки экспорттоо үчүн биз импорттоодо каалаган аталышты тандайбыз:
@A@import User from './user.js'; // сработает
import MyUser from './user.js'; // тоже сработает
// можно импортировать с любым именем, и это будет работать@A@
Ошентип, команда мүчөлөрү бир эле нерсени импорттоо үчүн ар кандай аттарды колдоно алышат жана бул жакшы эмес.
Адатта, муну болтурбоо жана кодду ырааттуу сактоо үчүн, эреже бар: импорттолгон өзгөрмөлөрдүн аттары файл аталыштарына дал келиши керек. Бул сыяктуу:
@A@import User from './user.js';
import LoginForm from './loginForm.js';
import func from '/path/to/func.js';@A@
...
Бирок, кээ бир командалар муну демейки экспортко каршы күчтүү аргумент деп эсептешет жана бардык жерде аталган экспортту колдонууну артык көрүшөт. Бир гана нерсе экспорттолгон күндө да, аны колдонбостон, аты менен экспорттолот default
.
Ал ошондой эле реэкспортту бир аз жеңилдетет (төмөндө караңыз).
Реэкспорт
"Реэкспорт" синтаксиси export ... from ...
бир нерсени импорттоого жана аны дароо башка ат менен экспорттоого мүмкүндүк берет, мисалы:
export {sayHi} from './say.js'; // реэкспортировать sayHi
export {default as User} from './user.js'; // реэкспортировать default
Бул эмне үчүн керек? Келгиле, колдонуунун практикалык мисалын карап көрөлү.
Элестеткиле, биз "пакет" жазып жатабыз: көптөгөн модулдары бар папка, анын ичинен кээ бир функциялар сыртка экспорттолот (NPM сыяктуу куралдар бизге ушундай пакеттерди жарыялоого жана жайылтууга мүмкүндүк берет) жана көптөгөн модулдар ички үчүн жөн гана жардамчы. пакеттин башка модулдарында колдонуу.
Файл структурасы мындай болушу мүмкүн:
@A@auth/
index.js
user.js
helpers.js
tests/
login.js
providers/
github.js
facebook.js@A@
...
Биз пакетибиздин функционалдуулугун бир кирүү чекити аркылуу жеткиликтүү кылгыбыз келет: "мастер файл" auth/index.js
. Ошентип, сиз аны төмөнкүдөй колдоно аласыз:
@A@import {login, logout} from 'auth/index.js'@A@
Биздин топтомду колдоно турган тышкы иштеп чыгуучулар пакетибиздин ичиндеги файлдарды аралап, анын ички түзүмү менен алек болбошу керек. Биз өзүбүзгө керектүү нерселердин баарын экспорттоп auth/index.js
, калганын сырттан жашырабыз.
Каалаган функциялар пакетибиздин модулдарына чачырагандыктан, биз аларды импорттойбуз auth/index.js
жана дароо сыртка экспорттойбуз.
@A@// 📁 auth/index.js
// импортировать login/logout и тут же экспортировать
import {login, logout} from './helpers.js';
export {login, logout};
// импортировать экспорт по умолчанию как User и тут же экспортировать
import User from './user.js';
export {User};@A@
...
Эми биздин пакеттин колдонуучулары жаза алышат import {login} from "auth/index.js"
.
Жазуу export ... from ...
бул импорт-экспорттун кыскараак версиясы:
@A@// 📁 auth/index.js
// импортировать login/logout и тут же экспортировать
export {login, logout} from './helpers.js';
// импортировать экспорт по умолчанию как User и тут же экспортировать
export {default as User} from './user.js';
...@A@
Реэкспорт Демейки Экспорт
Реэкспорттоодо демейки экспортту өзгөчө жол менен иштетүү керек.
Мисалы, бизде user.js
классты кайра экспорттоону каалайбыз User
:
@A@// 📁 user.js
export default class User {
// ...
}@A@
-
export User from './user.js'
иштебейт. Көрсө, бул эмне? Бирок синтаксистик ката болот!Демейки экспортту кайра экспорттоо үчүн,
export {default as User}
жогорудагы мисалдагыдай деп жазышыбыз керек. Бул жерде синтаксистин өзгөчөлүгү. -
export * from './user.js'
демейки экспортту кошпогондо, аталган экспортту гана реэкспорттойт.Эгерде биз аталган экспортту да, демейки экспортту да реэкспорттогубуз келсе, бизге эки нускама керек:
export * from './user.js'; // для реэкспорта именованных экспортов export {default} from './user.js'; // для реэкспорта по умолчанию
Демейки экспорт менен бул өзгөчө реэкспорттук жүрүм-турум кээ бир иштеп чыгуучуларга жакпай калган себептердин бири болуп саналат.
Бардыгы
export
Бул жерде биз ушул жана мурунку бөлүмдө камтылган бардык варианттар .
Аларды окуп, эмнени билдирерин эстеп, өзүңүздү сынасаңыз болот:
- Класс/функция/… декларациясынын алдында:
export [default] class/function/variable ...
- Өзүнчө экспорт:
export {x [as y], ...}
.
- Реэкспорт:
export {x [as y], ...} from "module"
export * from "module"
(реэкспорт кылбайтexport default
).export {default [as y]} from "module"
(реэкспорттор ганаexport default
).
Импорттоо:
- Модулдан аталган экспорттор:
import {x [as y], ...} from "module"
- Демейки импорттоо:
import x from "module"
import {default as x} from "module"
- Баары бир убакта:
import * as obj from "module"
- Модулду гана кошуңуз (анын коду иштейт), бирок аны өзгөрмөгө дайындабаңыз:
import "module"
import/export
Сценарийдин башына же аягына койсок болот , баары бир.
Башкача айтканда, техникалык жактан алганда, мындай белги абдан туура:
@A@sayHi();
// ...
import {sayHi} from './say.js'; // импорт в конце файла@A@
Иш жүзүндө, импорт көбүнчө файлдын башында жайгашкан. Бирок бул жөн гана ыңгайлуулук үчүн.
Импорт/экспорт билдирүүлөрү ичинде иштебей турганын эске алыңыз {...}
.
Төмөнкүгө окшогон шарттуу импорт иштебейт:
@A@if (something) {
import {sayHi} from "./say.js"; // Ошибка: импорт должен быть на верхнем уровне
}@A@
...Бирок биз чындап эле шарттарга жараша бир нерсени импорттоо керек болсочу? Же белгилүү бир убактабы? Мисалы, модулду керек болгондо гана жүктөйсүзбү?
Биз кийинки бөлүмдө динамикалык импортту камтыйт.