Если вы уже используете Javascript в своих проектах, вы, вероятно, используете множество операторов импорта/экспорта для разделения кода на модули.
Это то, что мы называем статическим импортом. Но что, если вы хотите импортировать модуль на лету? В этом случае вам нужно использовать декларацию динамического импорта.
Как это сделать? Давайте посмотрим вместе!
🔥Основы
На самом деле, использовать динамический импорт довольно просто. Выражение выглядит как оператор функции:
import('./path-to-my-module.js');
Это похоже на функцию, но это не так: она не наследуется от
Function.prototype
.
Интересная часть заключается в том, что динамический импорт возвращает промис: вам нужно обрабатывать его так же, как и для любого промиса в вашем коде.
🧑💻 Давайте программировать!
Я создал простой модуль с двумя именованными экспортами (константа и функция) и экспортом по умолчанию:
// 🗂 new-module.js const USERNAME_ID_KEY = 'id'; export const DEFAULT_USERNAME = 'John'; export const getUserId = (user) => user.id; export default USERNAME_ID_KEY;
Теперь давайте создадим новый файл для импорта нашего модуля:
// 🗂 index.js import('./new-module.js') .then(module => { console.log(module.DEFAULT_USERNAME); // => 'John' console.log(module.getUserId({ id: 123 })); // => 123 console.log(module.default); // => 'id' }) .catch(error => console.log('Error!'));
Как видите, это довольно просто: вы используете метод Promise
then
для получения объекта модуля, и каждый именованный экспорт находится под свойством. Для экспорта по умолчанию он находится под ключом default
.
Всегда полезно обрабатывать ошибки с помощью метода catch
просто потому, что его можно добавить.
Конечно, это работает и с async/await:
async function moduleLoading() {const {
DEFAULT_USERNAME,
getUserId, default: defaultModule,} = await import('
./new-module.js');
console.log(DEFAULT_USERNAME); // => 'John' console.log(getUserId({ id: 123 })); // => 123 console.log(defaultModule); // => 'id' } moduleLoading();
Обязательно укажите псевдоним для экспорта default
: default
— это ключевое слово в Javascript, и вы не можете использовать его для собственного именования.
📃 При использовании динамического импорта?
Я вижу два основных варианта использования для этого:
🪧 Условный импорт.
Самый очевидный способ — поставить условие под импорт огромного модуля. Поскольку вы можете вызвать import()
его в любом месте вашего кода, его можно поместить в условие. Например:
if (user.role === 'author') {
import('./author')
.then((authorModule) => {
console.log(authorModule.version);
});
}
🛣 Вычисляемый путь импорта.
Еще один отличный пример использования — загрузка модуля с вычисленным путем. Вы не можете сделать это со статическим импортом:
const VEHICULES = { CAR: 'car', BOAT: 'boat', }; const pathToUse = `./${VEHICLES.CAR}-module.js`; import(pathToUse) .then((module) => { // ... }) .catch((error) => console.log("Error!"));
🌼 Заключение
Как мы видели, этот вид импорта действительно прост в использовании и может быть очень мощным. Это звучит естественно с похожим на функцию import()
, а возвращаемый Promise
выглядит знакомо.
Надеюсь, вам понравился этот краткий обзор, не стесняйтесь 👏, если он показался вам интересным!