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
Webpack Workshop 1
By Vilva Athiban
Webpack Workshop 1
- 368