Webpack Overview
Tags: webpack
Published: 2020-08-01 00:00:00

---
date: '2020-08-01'
title: 'Webpack Overview'
published: true
description: 'Key concepts of Webpack'
tags: 
  - webpack
---

## Entry
An entry point indicates which module webpack should use to begin building out its internal dependency graph. 

## Output
The output property tells webpack where to emit the bundles it creates and how to name these files. It defaults to `./dist/main.js` for the main output file and to the `./dist` folder for any other generated file.

## Chunks
Chunks come in two forms:
- initial is the main chunk for the entry point. This chunk contains all the modules and its dependencies that you specify for an entry point.
- non-initial is a chunk that may be lazy-loaded. It may appear when dynamic import or SplitChunksPlugin is being used.


## Compilation
Compilation process: 

1. initialization： read arguments, load plugins and instantiate `Compiler`
2. start compilation
3. find entry
4. compile modules and call corresponding loaders: The loader transpiles the match modules.
5. complete compilation
6. output resources and produce chunks
7. complete output: write files to system
8. Webpack broadcast different events throughout the process, the plugins subscribe the events will be called and change the final output.

```mermaid
graph LR
  A[Compiler]-->B[Compilation]
  B-->C[Modules]
  C--Loaders-->D[Parser]
  D-->E[Output]
```

### Compiler Object
Compiler  is a singleton. It controls the whole bundling process. 
1. `acorn` library generates the `AST` tree for analyzing the relations of modules.
2. The final output is a `IIFE` function.
3. During the bundling process, modules are combined into chunks. Chunks combine into chunk groups and form a graph (ChunkGraph) interconnected through modules.

### Compiler Hooks
The Compiler module is the main engine that creates a compilation instance with all the options passed through the CLI or Node API. It is the context containing all information for bundling. Every hot reload and compiling, `compiler` creates a new `compilation` object. It extends the `Tapable` class in order to register and call plugins. Most user facing plugins are first registered on the Compiler. 

```js
compiler.hooks.someHook.tap('MyPlugin', (params) => {
  /* ... */
});
```

![image](https://user-gold-cdn.xitu.io/2018/12/1/16767ef8c28837ed?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)


### Compilation Object
The Compilation object has many methods and hooks available. On this page, we will list the available methods and properties.


### Compilation Hooks
The Compilation module is used by the Compiler to create new compilations (or builds). A compilation instance has access to all modules and their dependencies (most of which are circular references). It is the literal compilation of all the modules in the dependency graph of an application. During the compilation phase, modules are loaded, sealed, optimized, chunked, hashed and restored.

```javascript
compilation.hooks.buildModule.tap(
  'SourceMapDevToolModuleOptionsPlugin',
  (module) => {
    module.useSourceMap = true;
  }
);
```

### Hot Module Replacement
If Hot Module Replacement has been enabled via the HotModuleReplacementPlugin, its interface will be exposed under the module.hot property. 
```js
if (module.hot) {
  module.hot.accept('./library.js', function () {
    // Do something with the updated library module...
  });
}
```

#### Hot Module Replacement process

```mermaid
graph LR
check-->ready
ready-->apply
apply-->dispose
dispose-->apply
apply-->idle

```




## Loader
Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph.

1. **sync loader**
```javascript
/*
@param {string|Buffer} content Content of the resource file
@param {object} [map] SourceMap data consumable by https://github.com/mozilla/source-map
@param {any} [meta] Meta data, could be anything
*/
module.exports = function webpackLoader(content, map, meta) {
  // code of your webpack loader
}
```
2. **async loader**
```javascript
  module.exports = function webpackLoader(content, map, meta) {
      var callback = this.async();
      someAsyncOperation(content, function (err, result) {
          if (err) return callback(err);
          callback(null, result, map, meta);
      })
  })
```


## Plugin

### Creating a plugin
A plugin for webpack consists of:

A named JavaScript function or a JavaScript class.
Defines apply method in its prototype.
Specifies an event hook to tap into.
Manipulates webpack internal instance specific data.
Invokes webpack provided callback after functionality is complete.

```javascript
// A JavaScript class.
class MyExampleWebpackPlugin {
  // Define `apply` as its prototype method which is supplied with compiler as its argument
  apply(compiler) {
    // Specify the event hook to attach to
    compiler.hooks.emit.tapAsync(
      'MyExampleWebpackPlugin',
      (compilation, callback) => {
        console.log('This is an example plugin!');
        console.log(
          'Here’s the `compilation` object which represents a single build of assets:',
          compilation
        );

        // Manipulate the build using the plugin API provided by webpack
        compilation.addModule(/* ... */);

        callback();
      }
    );
  }
}
```