After React,Vue, this is the third front-end project that focuses on reading source code -Webpack. This paper is mainly based on:

  • WHY: Webpack source code
  • HOW: HOW to read the Webpack source code
  • WHAT: WHAT have you learned after reading the source code

Three directions.

Welcome to Star and subscribe to my blog.

WHY

Sure, Webpack is a front-end engineering tool that’s easy to understand and use, and doesn’t seem to need to be delved into. So why bother reading the source code? This, is writing this article I also asked. When outlining, people think that it is best to write WHY in a few sentences, but it turns out that it is worth saying more about it. Presume to read the Webpack source code partner’s possible motivation:

  1. Rich working experience
  2. True technology fans, know what it is and know why, and learn the method
  3. Related to work or personal projects, refer to study
  4. See someone write relevant article, also see understand next

The author starts with reason 4, then 1,2. Of course, 1,2 should be the motivation for most people to look at the project source code.

How

Build source code debugging environment

To read the source code, first get the source code, and then finally debug while reading. Of course, if your intelligence and reasoning skills are amazing, you can read them online on Github. There are two ways to download the source code. Git Clone, the most common git clone, will clone the Webpack project on Github to the local, pull and webpack official latest code to keep consistent, once and for all. However, when the author tried the first method, it was always unable to clone, probably because the Webpack source files were too large and the Github server clone was always slow. The next best thing is to download the Webpack source release. Select a version of the WebPack Source code you want to read and download the “Source Code (ZIP)”. It’s very fast because it doesn’t include.git.

IDE authors use VSCode, which makes it easy to debug node. Once you have the source code, create a new folder in the directory, write a simple webpack example, and debug it using VSCode. But in practice, Error: Cannot find module ‘json-parse-better-errors’ or Cannot find Module ‘webpack/lib/RequestShortener’, just run NPM install webpack webpack – cli – save – dev, can solve the error, and will not affect the debugging the source code.

After downloading, use VSCode to open Webpack-4.41.4 (modified), install dependencies, install webpack and webpack-CLI, press F5 to start debugging.

Debug, clarify the general pulse path

There is so much source code in Webpack that it is not necessary to read every line of code, but it is important to at least know how it runs, what core code it uses over and over again, and how the life cycle of each module works.

Find the core function source code

The amount of code makes it difficult to find the source code for the core functionality as you go through the process, at least for WebPack source code, because of its unique plug-in and callback structure. However, we can find and read the source code separately for each of the core features we want to understand. For example, if we want to see how Webpack generates bundle.js, webpack must call NodeJS file system output file method, search globally for “writeFile” to find the relevant code. Or use the bundle.js keyword “// Check if module is in cache”.

What

By reading the code while debugging, understanding where the code is going as a whole, and how WebPack generates bundle.js, the author learned the following:

  • Tapable plugin mechanism
  • A simplified Version of Webpack runs the process
  • How is bundle.js content generated

Tapable

Tapable in the source code application can be seen everywhere, to understand the source code, the first to learn Tapable mechanism. It’s not complicated, and we just need to know its basic functions and uses. Tapable can be understood as a hook callback mechanism. Each hook can subscribe to multiple functions, and the subscribed functions run when the hook is published. Here’s a simple example.

const { SyncHook } = require('tapable')
class Car {
    constructor() {
        this.hooks = {
           // # add a hook
            start: new SyncHook()
        }
    }
}
const car = new Car()
// start hook subscribes to a function
car.hooks.start.tap( 'run slowly', () = >console.log('start running slowly'))// start hook subscribes to another function
car.hooks.start.tap( 'run mediumly', () = >console.log('start running mediumly'))// Publish the hook
car.hooks.start.call()   // Run slowly run mediumly
Copy the code

A simplified Version of Webpack runs the process

How is bundle.js content generated

The uncompressed bundle.js file structure is generally as follows:

/ * * * * * * / (function(modules) { // webpackBootstrap
/ * * * * * * / 	// The module cache
/ * * * * * * / 	var installedModules = {};
/ * * * * * * /
/ * * * * * * / 	// The require function
/ * * * * * * / 	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: {}
/ * * * * * * /}; .Copy the code

So how does Webpack generate this content? In fact, Webpack processes content in two steps. The first step is to generate combined JS code through loader (default: babel-loader). The second step is to put the composite JS code into the Webpack default function to avoid variable leakage. Such as before package: foo.js

export const foo = (a)= > 'hello foo! '
Copy the code

bar.js

import { foo } from './foo.js'
foo()
console.log( 'hello bar! ' )
Copy the code

In the first step of packaging, generate the combined JS code from loader (default babel-loader) :

. const foo =(a)= > 'hello foo! '. \r\n__WEBPACK_MODULE_REFERENCE__0_666f6f_call__()\r\nconsole.log('hello bar! ')...Copy the code

Package the second step, combining the JS code into the WebPack default function.

/ * * * * * * / (function(modules) { // webpackBootstrap\n. const foo =(a)= > 'hello foo! '. foo()console.log( 'hello bar! ')...Copy the code

It is worth noting that the core file is concatenatedModule.js, which generates the packaged code by iterating through modulesWithInfo.

Q&A

1. What is Runtime?

Whether in webpack source code, Vue source code or elsewhere, runtime is a common occurrence. What exactly is runtime? After much review and refinement, the Runtime code can be understood as compiled code. For example, in React, runtime code is the JS code generated by compiling JSX code. For Vue, runtime code is JS code generated by compiling template,script, and style.

Hot updates, Code Splitting, tree-shaking, etc.

Webpack has a lot of content and core module principles, such as how loader works, Code Splitting, tree-shaking and hot loading. But after all, time is limited, the goal of reading the source code is not to understand all the content, but to master the main operation process of Webpack and understand several modules that are more interested in. So other module principles can be added to this article later. Interested in the corresponding module module partners can first search online related content.

Read the source code resource recommendations

  • how-react-works.pdf
  • Webpack – Wu Hao Lin
  • help developers better understand how webpack works: artsy-webpack-tour
  • build your own webpack

Thank you for taking the time to read this article. If you like this article, please like, bookmark and share, so that more people can see this article, which is also the biggest encouragement and support for me! Welcome to Star and subscribe to my original front-end technology blog.