предисловие
В одностраничных приложениях веб-пакетыдинамический импортФункция для асинхронной загрузки модулей, что позволяет уменьшить размер некоторых файлов. Мы можем предоставить через webpackimport()
а такжеrequire.ensure
Два API для использования этой функции.Поскольку оба метода принципиально одинаковы, примеры в этой статье основаны наimport()
метод.
начни с примера
основная среда
webpack 4.35.3
код
Вот самый простой пример, есть два файла,
index.js
это входной файл, который используетimport()
импортировать динамическиasync.js
документ.
index.js
async.js
мы выступаемwebpack --mode=development
чтобы получить скомпилированный файлmain.js
а также0.js
. в,main.js
Включатьindex.js
код,0.js
Включатьasync.js
код.
анализировать
главный вход
первый,main.js
Файл служит точкой входа для всего приложения, давайте посмотрим, что внутри.
Давайте сначала проигнорируем детальную логику кода.Посмотрев в целом, мы обнаружим, что этот файл на самом деле являетсясамовыполняющаяся функция, функция ставитпреобразованныйindex.js
а такжеПуть к файлусформироватьmodulesпереходит к основной функции.
В основной функции он будет выполнять__webpack_require__(__webpack_require__.s = "./src/index.js");
для инициализации входного модуля.
Функция этой функции заключается в загрузке и выполнении указанного модуля и возврате модуля.module.exports
.
Здесь вызывается исполнительный модульmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
для выполнения ранее переданногоmodule, то есть,преобразованныйindex.js
.
Давайте посмотрим на код в нем.
Обнаружитьimport
был преобразован в__webpack_require__.e(/*! import() */ 0)
, пойдем по следу и продолжим смотреть__webpack_require__.e
сделал что-то.
__webpack_require__.e
Код может быть немного ошеломляющим, но это не что иное, как делать что-то подобное.
- согласно с
installedChunks
Проверьте, загружен ли онchunk - Если не загружено, инициируйте
JSONP
запрос на загрузкуchunk - Настройте обработку ошибок для запроса, затем вернитеPromise.
Когда обещание вернется, оно продолжит выполнять наш предыдущий асинхронный обратный вызов запроса.
__webpack_require__.e(/*! import() */ 0)
.then(
__webpack_require__.bind(null, /*! ./async */ "./src/async.js")
)...
прямо звонил сюда__webpack_require__
загрузить наш异步模块
.
Тут два вопроса?
__webpack_require__
основано на том, что мы передали ранееmodules
получитьmodule
, однако, в__webpack_require__.e
не видел ни одногоmodules
Код для выполнения действия. Этоmodules
В конце концов это когда он обновится?promise
Пучокresolve
а такжеreject
все депонированоinstalledChunks
, не получается получить асинхронные чанкиonload
выполнить в обратном вызовеresolve
,Так,resolve
Когда оно было исполнено?
var promise = new Promise(function(resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
});
С сомнениями, давайте взглянем на загруженный0.js
содержание в .
Асинхронный блок
0.js
Логика здесь тоже очень проста, достаточно перейти кwindow["webpackJsonp"]
вpush chunkId
и содержитmodules
. давайте искатьwindow["webpackJsonp"]
, найти вmain.js
Есть такой кусок кода.
обычай здесьwebpackJsonpCallback
функциязаменятьохватыватьwindow["webpackJsonp"]
изpush
метод. Итак, прежде чем мы0.js
реализованоpush
На самом деле этореализован пользовательскийwebpackJsonpCallback
функция.
webpackJsonpCallback
Как видите, webpackJsonpCallback делает две вещи.
- воплощать в жизнь
installedChunks
серединаresolve
, Позволятьimport()
можно продолжать выполнять. - Буду
chunk
Все модули, содержащиеся в нем, зарегистрированы наmodules
в переменной.
Теперь мы окончательно разобрались со всем процессом асинхронной загрузки.
more
На самом деле приведенный выше код является лишь самым простым случаем, и конкретное содержание сгенерированной функции будет другим, поскольку код будет другим. Например, мы добавляем код предварительной загрузкиimport(/* webpackPrefetch: true */'./preload');
, Сгенерированоmain.js
В файле будет код для поддержки этой функции.Нетрудно понять, что цель веб-пакета - контролировать размер сгенерированного файла, и студенты, которые интересуются конкретными деталями, могут попробовать его локально.