2020-04-27

Learning Webpack core concept

Main reference:

Sean Larkin’s talk Everything’s a Plugin: Understanding Webpack From the Inside Out at JS Kongress 2019


Getting started:

Build modules on the browser including non-js file

$ webpack <entry.js>

$ webpack-dev-server –port=9000

Entry point

  • a module relys on other module, dependncies

  • the first js to load to ‘kick-off’ your app, a starting point for webpack to build the dependency graph

  • what to load for the browser; compliments the output property.

Output

  • where and how to distributes the bubdles (compilations)

  • default: bundle.js

Loaders

  • js functions that takes the source fiel, and return a modifed state

  • tell webpack how to load non-js file(transfer & interpretation)

  • return compliations

test

RegEx instructs the complier which files to run the loader against

use

An array/string/function which returns loader objects

enforce

Pre/post

run this rules before/after all other rules

include&exclude

Filter through

eg.node-modules

chaining loaders

order sensitive

like a streamline

Plugin

a class/instance which has an ‘apply’ method which can be used by complier to emit event

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
examplePlugin.protyotype.apply= funciton(complier){
if (typeof(process)!== 'undefined'){

complier.plugin('done',function(stats){
if (stats.hasErrors()){
process.stderr.wirte('\x07');
}
});

complier.plugin('failed',function(err){
process.stderr.wirte('\x07');
});
}
}
module.exports= examplePlugin;

To use:

require() plugin from node_modules into config

add new instance of plugin to plugin keys in config object

provide additonal info for arguments

Tapable

backbone of webpack plugin

mixin

Apply plug asyn / parallel

Event emitter/hook

1
2
3
4
5
6
7
8
class basicPlugin {
constructor() {}
apply(complier) {
compiler.plugin('make', (compilation) => {
console.log('access to the compilation');
});
}
}
1
2
3
4
5
class somePlugin{
apply(complier){
compiler.plugin('run',(compilation,cb)=>{...})
}
}

the plugin is registerd via compliers inherited apply function

1
2
3
4
class Compiler extends Tapable{
//some fn...
this.apply.plugsAsync('run',this,()=>{...})
}

Tapable instances call apply.plugins() and pass the event and state through to plugin

.run() -> trigger the hook

Tapable instance

1

7 instances of Tapable

  • Compiler

    • 3
  • exposed via node API

  • central dispatch

  • Start/stop

  • const webpack = require ('webpack');
    const complier = webpack(<config>);
  • Compilation (dependency graph)

    • created by the complier
    • contains the dependency graph traversal algo
  • Resolver

    • Finds the dependencies file
    • Verifies the file exists
    • turn partial path to abso path
    • return the path, context, request
  • Module Factories

    • Takes resolved request
    • collect the source
    • Returns Module object
  • Parser

    • 4
    • Convert a module object turns to AST tree
    • finds all require/import and turn to dependency’s
  • {Template}

    • 5
    • Binding data with view/module
    • config props
    • Dep graph state
    • template jsx
    • Chunk ->module ->dependncies
    • render() to bundle.js

    How webpack builds the dependency graph

  • 6
  • the complier reads the options and create compilations

    7
  • after the resolver verfied these files, returns the normal modules

  • 8
  • the parser, if non-js pass it to the loader, if it’s JS attach the dependencies to the module after resolved them

  • use template and module factore to remove/replace the require/import to run the app on browser

    HOW A MODULE GETS TO THE BROWSER /w webpack

  • 9
    • 10
    • 11
    • 12
    • 13
    • 14

Cache-loader

Webpack-dev-middleware


Credits

all images in this post originats from the slides of this talk Sean Larkin’s talk Everything’s a Plugin: Understanding Webpack From the Inside Out at JS Kongress 2019