Webpack In & Out

Advanced Workshop by Vilva Athiban

AGENDA

  • Webpack Origins
  • Webpack Basics
  • Config Webpack
  • Human <=> Webpack
  • HMR
  • Loaders
  • Compiler
  • Plugins & Source code : Birds-eye view
  • Code Spliting
  • Optimizations for Prod
  • Source Maps
  • Webpack 5 Migration & MF
  • Q/A and Fun time

WEBPACK ORIGINS

Long Long ago...

Two ways to Load JS:

// index.html

<html>
  <head></head>
  <body>
  
    <script type="text/javascript">
        console.log("Inline Javascript")
    </script>


    <script type="text/javascript" src="pathToJSFile.js" />
    
  <body />
</html>

// pathToJSFile.js

console.log("test");

Problems

Not Scalable

Many Scripts -> Performance bottleneck

One large Script -> Not Maintainable

Scope Issues

IIFE

IIFE - Immediately Invoked Function Expression

 

Avoids Scope collisions


Tools: Gulp, Grunt

(function add(a, b) {
	return a + b
}) (3,5);

Problems

Dead/ Unused Code


Rebuilds

No Lazy Loading

Common JS

Evolution of NodeJS creates Common JS modules

Node +  modules(common js) + NPM = Awesome

// Named import/export

// add.js
exports.add = () => { /* do add */ }

//index.js
const {add} = require('./add.js');


// Default import/export

// add.js
module.exports = () => { /* do add */ }

//index.js
const anyName = require('./add.js');

Problems

No Browser Support

Early Bundlers/Loaders

Loaders load and transpile at runtime

Bundlers transpile and bundle before hitting the browser

 

Code in Common JS => Bundle it together 

 

Supports Browser directly

RequireJS

Problems

Debugging such code is a big issue

Code can be AMD as well, which is a problem

No Lazy load / Async bundling

ES Modules

Reusable & Scalable

 

Better Syntax than CommonJS

// Named import/export

// add.js
export const add = () => { /* do add */ };

//index.js
import {add} from './add.js'

// Default import/export

// add.js
export default () => { /* do add */ };

//index.js
import anyName from './add.js'

Problems

Node has no support (In older versions)
 

Slow in Browsers (when not transpiled)

We NEED a HERO

Webpack

Write in any Format -> Convert for Browser

Async Bundling and Lazy loading

Bigger EcoSystem

Bundle more than JS & JSON

Get equipped with Plugins and Loaders

WEBPACK BASICS

WEBPACK ARCHITECTURE

Entry

Single Entry - Default (src/indexjs)

{
	entry: "./src/home.js",
	output: {
          filename: 'bundle.js'
      }
}

Object Syntax

{
	entry : {
            main: "./src/main.js",
            vendor: "./src/vendor.js"
      	},
	output: {
    		filename: 'bundle.js'
    	}
}
{
	entry : {
            main: "./src/main.js",
            vendor: "./src/vendor.js"
      	},
	output: {
    		filename: '[name].bundle.js'
    	}
}

Entry

Multi Entry

{
	entry: {
          pageOne: './src/pageOne/index.js',
          pageTwo: './src/pageTwo/index.js',
          pageThree: './src/pageThree/index.js'
      }
	output: {
          filename: '[name].[contenthash].bundle.js'
      }
}

Output

Multi Entry

{
	entry: {
          pageOne: './src/pageOne/index.js',
          pageTwo: './src/pageTwo/index.js',
          pageThree: './src/pageThree/index.js'
      }
	output: {
          filename: '[name].[contenthash].bundle.js',
          path: __dirname + '/dist',
          publicPath: "http://pathToCDN/dist"
      }
}

To assign public path in runtime : __webpack_public_path__

Loaders

Its a function

Transforms Source code to JS

Chaining of loaders executes in reverse order


	module: {
    		rules: [
            	{
                	test: \.css$/,
                 	use: [style-loader, css-loader]
                }
            ]
	}

Plugins

Its a class/object with `apply` method

Access entire Compiler lifecycle


plugins: [
	new PluginName( { ...optionsIfAny } )
]

Webpack Modules

Import

Require

Define

@import

url()

<img src="" />

__webpack__require

Targets

Node, electron, web, web-workers etc

One code - multiple targets



module.exports = [ wpConfigForNode, wpConfigForWeb, wpConfigForElectron]

Other topics

Caching

Dependency Graph

Runtime

Browser Compatability

CONFIG WEBPACK

Human <=> Webpack

Steps

  • Module Graph
  • Chunk Graph
  • Optimize
  • ID Generation
  • Code Generation & Cache
  • Assets Generation

HMR

Two moving parts of HMR

Update Manifest

Updated Chunk

Loaders

Important Ones

  • file loader/url loader
  • css loader/styles loader
  • less/sass/postcss loader
  • babel-loader

Custom Loader

Compiler

Tapable

Webpack itself is built by many plugins

 

Tapable is basic utility for such plugins to access hooks of various events

Plugins &
Source code : Birds-eye view

Important Ones

  • HtmlWebpackPlugin
  • MiniCssExtractPlugin
  • ProgressPlugin
  • TerserPlugin

A Peak into Source code

Custom Plugins

Code Spliting

Dynamic Import automates code-splitting

Vendor chunks possible with splitChunks

 

Lazy loading & Caching

Optimizations for Prod

Magic Comments

Preload/Prefetch

 

Hashing

Compression

Source Maps

Algorithm: Base64 VLQ


• Generated column

• Original file this appeared in

• Original line number

• Original column

• And if available original name

 

Map with comment : // sourceMappingURL

Webpack 5 Migration

Major Improvements 

  • Faster builds with persistent caching
  • Smaller bundle sizes
  • Better long term caching
  • Removed Deprecated Items
  • Node.JS polyfills removed

Module Federation

Q&A

Fun time

Made with Slides.com