В начале прошлого года было предложено ввести в JavaScript возможность динамического импорта. Если кто не знает, то сейчас в JavaScript нативно поддерживается только статическая импортизация и для этого есть причины, но это тема отдельного разговора. Предложение было реализовано и включено в список ближайшего обновления ECMAScript. Google Chrome с 63 версии уже поддерживает эту возможность. Я немного расскажу что это такое и где это может пригодиться.
Динамический импорт (dynamic import) используется почти также как и статический, но имеет несколько ключевых отличий:
Синтаксически динамический импорт подобен вызову функции: import(‘path/to/module.js’);
Команда import(‘path/to/file.js’) возвращает Promise, который перейдет в состояние fulfilled после того, как будет подтянут и установлен сам модуль непосредственно, так и все его зависимости. А это значит, что мы можем написать вот так:
import('path/to/module.js')
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
Или даже так:
const module = await import('path/to/module.js');
Важное замечание: хотя динамический импорт синтаксически и выглядит как вызов функции import(), но функцией не является. Он не наследуется от Function.prototype, а это значит что его нельзя вызвать через call или apply.
Применений динамическому импорту можно найти много, require.js уже давно имеет подобную возможность и webpack, если не ошибаюсь тоже, поэтому многие из вас, наверное, уже давно используют подобный функционал. Теперь это делать можно будет нативно. Но с другой стороны, возможность импортировать динамически, в зависимости от условий, во время рантайма дает и место для более запутанного кода, хотя понимаю что налепить плохой код можно с чем угодно, не в инструменте дело. Пишите ваше мнение в комментарии, что вы думаете о dynamic import.
Более детально можно почитать и посмотреть тут:
https://github.com/tc39/proposal-dynamic-import
https://developers.google.com/web/updates/2017/11/dynamic-import
https://www.youtube.com/watch?v=eg8eLH52d4s&t=31s
Комментарии (14)
helgihabr
07.06.2019 10:50Пока в FF javascript.options.dynamicImport не будет включен по-умолчанию, нативно использовать динамический импорт рановато.
Кстати, подскажите, как дела обстоят с этим в IE или Edge? Или что там в Windows используется.ihost
07.06.2019 10:59+1В Edge и Safari эта фича уже давно поддерживается и работает — больше двух лет как — см. https://habr.com/ru/company/tuturu/blog/326716/ — как собственно и с множеством современных ES-фичей, которые в Edge поступают раньше, чем в хром
MikeLP
07.06.2019 13:22Начиная с 67 версии FF поддерживает динамический импорт по умолчанию.
helgihabr
07.06.2019 13:28Хм, действительно, так. Спасибо.
FF 67+From version 66 until version 67 (exclusive): this feature is behind the javascript.options.dynamicImport preference (needs to be set to true). To change preferences in Firefox, visit about:config.apapacy
07.06.2019 14:40Не уверен что использовать нативно вообще перспективная идея. Это немного напоминает requirejs Сначала все ображдовались что можно импортировать зависимости а не прописывать все в тэгах script. Потом оказалось что загрузка сотен мелких модулей это очень долго и стали все rj-иксить в один огромный файл. Потом и это оказалось ужасно т.к. долго. И тут пришли чанки которые регулируются как раз динамическим импортом.
ihost
07.06.2019 11:03+1Google Chrome с 63 версии уже поддерживает эту возможность
А Edge и Safari поддерживают эту фичу уже два года — https://habr.com/ru/company/tuturu/blog/326716/. Оперативно, может еще через десяток лет хром наконец-то оптимизирует потребление памяти до уровня Edge
apapacy
В вебпаке динамический импорт сейчас это одна из ключевых фич которую используют практически все для разделения кода на чанки. В этом собственно и заключается основная функциональность данного конструкции.
worldxaker
ага, от того ещё более странно что в одной из последних версий вебпака его сломали и до сих пор не починили
apapacy
У мен я сейчас такой по версиям в одном из проектов стек (начал н этой недели с нуля) чанки работют как положено. Но правда я с плагинами это делаю.
worldxaker
не туда
Odrin
А что конкретно сломали, можно ссылку на issue?
worldxaker
github.com/webpack/webpack/issues/8656
Odrin
Ну и как бы ошибка в npm, а не webpack.