The words written in the front

In the process of reading Webpack 4.x source code, reference to the “Simple webpack” book and many great god’s article, combined with their own experience, summarized as follows.

An overview

Webpack is like a production line that goes through a series of processes to convert source files into output. Each process on this production line has a single responsibility. There are dependencies between multiple processes. Only after the current process is completed can the next process be handled. A plug-in is like a function that plugs into a production line and works with resources on the production line at a specific time. Webpack organizes this complex production line through Tapable. Webpack broadcasts events as it runs, and the plug-in only needs to listen for the events it cares about to join the production line and change how the production line works. Webpack’s event flow mechanism ensures the orderliness of plug-ins and makes the whole system very extensible. — Wu Haolin, “Simple Webpack”

Core concepts

Entry, loader, Plugin, Module, chunk, no matter documents or related introduction are many, do not repeat, there is a question of the document.

The build process

The running flow of WebPack is a sequential process, from start to finish:

  1. Initialization parameters: from the configuration file andShellStatement read and merge parameters, get the final parameter;
  2. Start compiling: Initialize with the parameters obtained in the previous stepCompilerObject, loads all configured plug-ins, executes the object’srunMethod starts compiling;
  3. Identify entry: Locate all entry files according to the entry in the configuration
  4. Module compilation: Starting from the entry file, call all configured Loader to translate the module, find out the module that the module depends on, and then recurse this step until all the entry dependent files have gone through this step;
  5. Complete module compilation: After using Loader to translate all modules in step 4, obtain the final content of each module after translation and the dependencies between them;
  6. Output resources: Assembled into modules based on the dependencies between entry and moduleChunkAnd then put eachChunkConvert to a separate file and add it to the output list. This step is the last chance to modify the output.
  7. Output complete: After determining the output content, determine the output path and file name based on the configuration, and write the file content to the file system. In the process above,webpackA specific event is broadcast at a specific point in time, and the plug-in executes specific logic when it listens for an event of interest, which the plug-in can callwebpackAPI changes providedwebpackRun result of.

Compare the two core objects in webpack

  • CompileObject: responsible for file listening and starting compilation.CompilerExample contains the completewebpackConfiguration, global only oneCompilerInstance.
  • compilationObject: whenwebpackRun in development mode, every time a file change is detected, a new oneCompilationWill be created. aCompilationObject contains the current module resources, build resources, changing files, and so on.CompilationObject also provides many event callbacks for plug-ins to extend.
  • Both objects inherit fromTapable. In order toCompileAs an example
const {
	Tapable,
	SyncHook,
	SyncBailHook,
	AsyncParallelHook,
	AsyncSeriesHook
} = require("tapable");

class Compiler extends Tapable {
	constructor(context) {
		super();
		this.hooks = {
			/** @type{SyncBailHook<Compilation>} */ / All the files that need to be exported have been generated, asking the plug-in which files need to be exported and which files do not need to be exported. shouldEmit: new SyncBailHook(["compilation"], / * * @)type{AsyncSeriesHook<Stats>} */ / successfully complete a completed compilation and output process.done: new AsyncSeriesHook(["stats"], / * * @)type {AsyncSeriesHook<>} */
			additionalPass: new AsyncSeriesHook([]),
			/** @type {AsyncSeriesHook<Compiler>} */
			beforeRun: new AsyncSeriesHook(["compiler"], / * * @)type{AsyncSeriesHook<Compiler>} */ / Run: new AsyncSeriesHook(["compiler"], / * * @)type{AsyncSeriesHook<Compilation>} */ / After determining which files to output, execute the file output. You can obtain and modify the output here. emit: new AsyncSeriesHook(["compilation"], / * * @)type{AsyncSeriesHook<Compilation>} */ /"compilation"], // All the above events (except run, beforerun) are output events /** @typeThisCompilation: new SyncHook([CompilationParams>}"compilation"."params"], / * * @)type{SyncHook<Compilation, CompilationParams>}"compilation"."params"], / * * @)type{SyncHook<NormalModuleFactory>} */ // The compilation of NormalModuleFactory parameters: new SyncHook(["normalModuleFactory"], / * * @)type{SyncHook<ContextModuleFactory>} */ // Compilation: ContextModuleFactory: new SyncHook(["contextModulefactory"], / * * @)type {AsyncSeriesHook<CompilationParams>} */
			beforeCompile: new AsyncSeriesHook(["params"], / * * @)type{SyncHook<CompilationParams>} */ / The compiler object compile: new SyncHook([compiler object compile: new SyncHook(])"params"], / * * @)type{AsyncParallelHook<Compilation>} */ / A new Compilation is created, which is to read files from Entry, compile files according to the file type and configuration of the Loader, and then find the files that the file depends on. Recursive compilation and parsing. make: new AsyncParallelHook(["compilation"], / * * @)type{AsyncSeriesHook<Compilation>} * compile: new AsyncSeriesHook(["compilation"], / * * @)type{AsyncSeriesHook<Compiler>} */ / watchRun: new AsyncSeriesHook(["compiler"], / * * @)type {SyncHook<Error>} */
			failed: new SyncHook(["error"], / * * @)type {SyncHook<string, string>} */
			invalid: new SyncHook(["filename"."changeTime"], / * * @)type{SyncHook} */ / watchClose: new SyncHook([]), // TODO the following hooks are weirdly located here // TODO move themfor webpack 5
			/** @type{SyncHook} */ / initialization phase: Start applying node.js-style file systems to compiler objects to facilitate subsequent file finding and reading. environment: new SyncHook([]), /** @typeAfterEnvironment: new SyncHook([]), /** @type{SyncHook<Compiler>} */ // afterPlugins: new SyncHook([)"compiler"], / * * @)type {SyncHook<Compiler>} */
			afterResolvers: new SyncHook(["compiler"], / * * @)type{SyncBailHook<string, EntryOptions>} */ / instantiate an EntryPlugin for each Entry to prepare for recursive parsing of the Entry. entryOption: new SyncBailHook(["context"."entry"])};Copy the code

During WebPack execution, a sequence of events is broadcast — a sequence of events in this.hooks (similar to the life cycle in our usual framework), in which order the subscribers to these events are organized, executed, parameter passed… That’s what Tapable does. I would like to recommend a popular science article about Tapable

Process details

Refer to my comments in the referenced Compile object for details of the process, one thing to note is that the order in which the author hooks write is not the order in which they are called. There are several cases of uncommented ones:

  1. Less important, or known by event name and context
  2. I don’t know for the time being.
  3. Of course the most important events basically covered here are supplemented by a large figure from the reference article

Compilation Process Introduction

A compilation is actually a process of calling the corresponding loader to process files to generate chunks and optimize them. Several key events (in the Compilation object this.hooks) :

  1. buildModuleUse the correspondingLoaderTo convert a module;
  2. normalModuleLoaderIn the useLoaderAfter converting a module, useacornParses the transformed content and outputs the corresponding abstract syntax tree (AST) for conveniencewebpackPost-code analysis.
  3. sealAll modules and their dependent modules passLoaderAfter the transformation is complete, the generation begins based on the dependenciesChunk.

Finally, a picture is taken from the reference article for a clearer understanding of the whole process

reference

  1. Taobaofed.org/blog/2016/0…
  2. Imweb. IO/topic / 5 baca…
  3. Simple Webpack

Spread the word

This article is published in Front of Mint Weekly. Welcome to Watch & Star.

Welcome to the discussion. Give it a thumbs up before we go. ◕ ‿ ◕. ~