Webpack - Behind the Scenes

Imran Sayed
4 min readMar 25, 2019

--

This blog would tell you how webpack actually works behind the scenes.

It's interesting to know that 80% of the webpack is made up of its own plugin system. Webpack itself is an event-driven architecture. Plugins are a key piece of the webpack ecosystem and provide the community with a powerful way to tap into webpack’s compilation process. A plugin is able to hook into key events that are fired throughout each compilation.

A small library called Tapable is a core utility in webpack. Many objects in webpack extend the Tapable class. The class exposes tap, tapAsync, and tapPromise methods which plugins can use to inject custom build steps that will be fired throughout a compilation.

How does webpack work behind the scenes?

In a nutshell, when a module comes to webpack , the webpack compiler puts into a container called chunk, and executes a lot of plugins onto it ( to typologically sort it and optimize it ) before its rendered onto the browser.

Let's dive deep into how that works,

The very first code that is executed in Webpack is the Node API ( you can check webpack.js file ).

Let's break the steps into the following:

1-Compiler — When a module comes to Webpack, the first thing that is run is Compiler ( compiler.run() in webpack.js), that’s your tapable instance. Its the top level, central dispatch for webpack. Its has Hooks — which control when webpack starts/stops, emit assets, watch mode etc. You can find codes for the Compiler in Compiler.js

compiler.run(): node_modules/webpack/lib/webpack.js
Hooks: node_modules/webpack/lib/Compiler.js

2-Compilation/Dependency Graph — The compiler then creates Compilation. Compilation is the heart of Webpack, where webpack kicks off building the graph, ceiling it and rendering it into bundles. ( Both Compiler and Compilation classes extend the Tapable class)

node_modules/webpack/lib/Compilation.js

3-Resolver — When you pass your entry point to webpack , it gives it to the Resolver, which checks if a given partial path exits, and return the full absolute path along with extra info like context, request, calls etc. Example, when you use, require a statement in node, you send it the module resolver to make sure it exists. ( ResolverFactory.js )

4-Module Factories — Factories create objects or instances. So module factories create module instances. Module factories then take a successfully resolved request from the resolver, collects the source code from that file and create a module object/instance( NormalModuleFactory.js & ContextModuleFactory.js )

5-Parser — A parser takes a string of source code and converts it into AST( Abstract Syntax Tree ) ( https://astexplorer.net/ ). Webpack has a parser class that uses acron parser, which takes the Module Object ( containing the source code ) created by Module Factory and creates an AST out of it. Webpack traverses through entire AST. It also finds all the require and import from AST statements and creates a dependency graph. It attaches those dependencies to the modules. It’s important to note that if webpack finds any rules for loaders, the loaders convert those codes( e.g. css files ) into JavaScript, and then Parser parses them into AST.

6-Templates — Templates will then do the data binding for your parsed module objects and generate the code that you see in the bundled javascript file. It renders a chunk that contains module in an array. So the whole module can be broken into three parts:

1-Chunk Template
2-Module Template
3-Dependency Templates

And this process is repeated until it has resolved all of its dependencies. The core job of webpack is to resolve files and tie everything up in a single dependency graph. This helps webpack in the incremental build. The abstraction, given in webpack and its architecture allows us to instantly pivot and add any feature we want. Because of this, we are able to develop and publish really quickly.

Tree shaking and Dead Code Elimination

Tree shaking or Live Code inclusion means that webpack uses the syntax statically to identify, what is being used and bundles only that. This means that it will only bundle those functions or constants which are being imported or used in your main index.js file.

Dead Code Elimination is a compiler optimization to remove the code that does not affect the program result.

--

--

Imran Sayed
Imran Sayed

Written by Imran Sayed

👤 Full Stack Developer at rtCamp, Speaker, Blogger, YouTuber, Wordpress, React, Node, Laravel Developer http://youtube.com/ImranSayedDev

Responses (1)