Скомпилируйте и соберите веб-пакет

внешний интерфейс переводчик браузер Webpack

предыдущий постПодробное объяснение веб-пакетаПредставленный в веб-пакете на основе программирования потока событий, он представляет собой набор подключаемых модулей высокого уровня и представляет собой процесс компиляции веб-пакета в целом. В этой статье мы поговорим о самой основной части — компиляции и сборке.

компиляция веб-пакета

Важные узлы сборки

Следующие узлы событий всегда возникают при построении webpack.

  • перед запуском очистить кеш
  • запустить хук данных кэша регистров
  • компилировать начать компилировать
  • make анализирует зависимые и косвенно зависимые модули от записи и создает объект модуля
  • сборка модуля модуля сборки
  • seal Результат сборки запакован и не может быть изменен.
  • after-compile завершает сборку, кэширует данные
  • вывести вывод в каталог dist

вmakeЭто самая основная часть всей сборки, создание модулей с помощью функции фабрики модулей, а затем компиляция модулей.

Компиляция в make hook

Alt text
упомянутый выше*ModuleFactoryОтносится к функции фабрики модулей.Причина, по которой есть такая функция, как фабрика модулей, а также из веб-пакетаentryГоворя о конфигурации, в элементе конфигурации веб-пакетаentryПоддерживаются следующие типы:

  • тип персонажаstring
  • тип массива символов[string]
  • Тип пары "ключ-значение" многостраничного объектаobject { <key>: string | [string] }
  • Также поддерживает функцию, которая возвращает построенную запись(function: () => string | [string] | object { <key>: string | [string] })

Чтобы в будущем обрабатывать различные типы входных модулей, необходима фабрика модулей для обработки различных типов входных модулей.

  • singleEntry: string|object { <key>: string }
  • мультизапись:[string]|object { <key>: [string] }
  • динамическая запись:(function: () => string | [string] | object { <key>: string | [string] })

На приведенном выше рисунке для того, чтобы просто проиллюстрировать процесс построения, самый непосредственныйsingleEntryГоворя о типах, для таких входных модулей webpack используетNormalModuleFactoryДля создания модуля вызывается тип создаваемого модуляNormalModule,существуетNormalModuleСпособ сборки модуляbuild,использоватьrunLoadersЗагрузите модуль, затем используйте его для синтаксического анализа, анализа зависимостей модуля и рекурсивной сборки.

Создайте уплотнение пакета

К моменту этапа построения и упаковки построение кода завершено, но как организовать эти коды по логике ссылок на зависимости, когда браузер загружает встроенный вами код в браузер, он еще может выполняться корректно. пройти в вебпакManifestЗапишите подробные пункты каждого модуля, черезRuntimeДля начальной загрузки, загрузки и выполнения кода модуля, особенно асинхронной загрузки.

###Время выполнения Как упоминалось выше, мы лишь кратко представим их здесь. Среда выполнения и сопутствующие данные манифеста в основном относятся ко всему коду, который использует веб-пакет для подключения модульного приложения во время выполнения в браузере. Среда выполнения содержит: Логику загрузки и синтаксического анализа, необходимую для подключения модулей по мере их взаимодействия. В том числе подключение загруженных модулей в браузере и логика выполнения лениво загруженных модулей.

###Манифест Так что же происходит, когда ваше приложение, например файл index.html, некоторые пакеты и различные ресурсы, загружаются в браузер? Файловая структура вашего тщательно организованного каталога /src теперь исчезла, так как же webpack управляет взаимодействием между всеми модулями? Вот где появляется использование данных манифеста... Когда компилятор начинает выполнять, анализировать и отображать приложение, он сохраняет подробные маркеры всех модулей. Этот набор данных называется «Манифест», и когда он упакован и отправлен в браузер, манифест используется для анализа и загрузки модулей во время выполнения. Какой бы синтаксис модуля вы ни выбрали, эти операторы import или require теперь переводятся вwebpack_requireметод, который указывает на идентификатор модуля. Используя данные в манифесте, среда выполнения сможет запросить идентификатор модуля и получить за ним соответствующий модуль.

Определяет функцию немедленного выполнения, объявляет__webpack_require__, для загрузки различных модулей.

(function(modules) { // webpackBootstrap
    var installedModules = {}; // cache module
    function __webpack_require__(moduleId) { // 模块加载
        // Check if module is in cache
        if (installedModules[moduleId]) {
            return installedModules[moduleId].exports;
        }
        // Create a new module (and put it into the cache)
        var module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}
        };
        // Execute the module function
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
        // Flag the module as loaded
        module.l = true;
        // Return the exports of the module
        return module.exports;
    }

    // expose the modules object (__webpack_modules__)
    __webpack_require__.m = modules;

    // expose the module cache
    __webpack_require__.c = installedModules;

    // define getter function for harmony exports
    __webpack_require__.d = function(exports, name, getter) {
        if (!__webpack_require__.o(exports, name)) {
            Object.defineProperty(exports, name, {
                configurable: false,
                enumerable: true,
                get: getter
            });
        }
    };

    // getDefaultExport function for compatibility with non-harmony modules
    __webpack_require__.n = function(module) {
        var getter = module && module.__esModule ?
            function getDefault() { return module['default']; } :
            function getModuleExports() { return module; };
        __webpack_require__.d(getter, 'a', getter);
        return getter;
    };

    // Object.prototype.hasOwnProperty.call
    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

    // __webpack_public_path__
    __webpack_require__.p = "";

    // Load entry module and return exports
    return __webpack_require__(__webpack_require__.s = 0);
})([/**modules*/])

Фрагмент кода, упомянутый выше, представляет собой загрузочный код, который выполняется в браузере после сборки веб-пакета. что упомянуто вышеruntime. Это функция немедленного исполнения, тогда параметрmodulesнадManifest, чтобы организовать логику зависимостей каждого модуля.

(function(modules){
	// ...
	// runtime
	function __webpack_require__(moduleId) {
		// 加载逻辑
	}
	// ...
})([function (module, exports, __webpack_require__) {

    var chunk1 = __webpack_require__(1);
    var chunk2 = __webpack_require__(2);
   
}, function (module, exports, __webpack_require__) {

    __webpack_require__(2);
    var chunk1 = 1;
    exports.chunk1 = chunk1;
}, function (module, exports) {

    var chunk2 = 1;
    exports.chunk2 = chunk2;
}])

сказано вышеruntimeа такжеmanifestтолько что вsealпоэтапная инъекция

class Compilation extends Tapable {
   
    seal(callback) {
        this.hooks.seal.call();
        // ...
        if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
            this.hooks.beforeChunkAssets.call();
            this.createChunkAssets();
        }
        // ...
    }
  
    createChunkAssets() {
	    // ...
		for (let i = 0; i < this.chunks.length; i++) {
			const chunk = this.chunks[i];
			// ...
				const template = chunk.hasRuntime() 
					? this.mainTemplate
					: this.chunkTemplate; // 根据是否有runTime选择模块,入口文件是true, 需要异步加载的文件则没有
				const manifest = template.getRenderManifest({ 
					// 生成manifest
					chunk,
					hash: this.hash,
					fullHash: this.fullHash,
					outputOptions,
					moduleTemplates: this.moduleTemplates,
					dependencyTemplates: this.dependencyTemplates
				}); // [{ render(), filenameTemplate, pathOptions, identifier, hash }]
				// ...
    }
}

пройти черезtemplateНаконец, организуйте код, встроенный код, показанный выше,mainTemplateГенерируется.

напиши в конце

пройти черезtemplateСгенерируйте окончательный код, сборка завершена, следующий шаг — вывод кода вdistсодержание.

наконец

Инженерное решение команды Tencent IVWEBfeflowОткрытый исходный код: домашняя страница Github: https://github.com/feflow/feflow