Module Bundlers: Webpack

Problem: Using one JS file inside another  

Suppose you have two files: 

math.js (exports a function)  
main.js (wants to use that function) 


Issue: Browser doesn’t understand imports automatically  
  1. main.js doesn’t know about math.js  
  2. There’s no built-in way to "import" functions before ES6 modules  
  3. This leads to errors like add is not defined

Common workaround before module bundlers

Using <script> tags (manual loading)

html
<script src="math.js"></script>
<script src="main.js"></script>

Problem:  
  1.    Order matters! math.js must be before main.js  
  2.   Too many <script> tags if we have multiple files  
  3.   No way to bundle or optimize files  

How Webpack Helps

1. Allows using import/export syntax


2. Webpack bundles all files into one

Instead of manually loading multiple scripts, Webpack combines them into a single bundle.js, which can be included in HTML:
<script src="bundle.js"></script>

3. Optimizes the code

  1.    Removes unused code (tree shaking)  
  2.    Minifies for better performance 

Conclusion 

  1. Before module bundlers → We manually managed multiple <script> files.  
  2. Webpack → Automates bundling, resolves dependencies, and optimizes code. 

WEBPACK

1. Dependency Resolution

  1. Every app has a main JS file (the entry point).  
  2. This file imports other files, which may import even more files.  
  3. Webpack scans all `import` and `export` statements to track dependencies until it finds files with no further imports.  
  4. Dependencies are not just JS files—they can be CSS, images, or libraries (like Lodash


2. Bundle

  1. Once dependencies are resolved, Webpack bundles everything into one or more files.  
  2. Bundling combines all necessary files into a single `bundle.js` (or multiple optimized chunks).  
  3. This reduces HTTP requests and ensures correct loading order.

3. Transform

  1. During the bundle process, if there are any non-JS files such as css files, webpack 1st "transforms" the css into js file (modules with imports/exports). 
  2. At runtime, Webpack injects the CSS into a `<link>` tag, making it work like a regular CSS file.


EXAMPLE

A new file called "webpack.config.json" needs to be created. A basic config should have 3 things
  1. Entry file name
  2. Output folder path for bundled file
  3. Output file name for bundled file

Let's say we have a Calculator app. 
webpack-basic-example/
│── src/
│   ├── index.js
│   ├── sum.js
│   ├── product.js
│   ├── utils.js
│   ├── data.js
│── dist/
│── package.json
│── webpack.config.js




 








Now Run

npm run build
This generates a dist/bundle.js file.

HANDLING CSS FILE

Webpack doesn’t understand CSS by default, so we need to install loaders to handle it. To handle CSS file, we need to modify the webpack file 

Install CSS Loaders 

npm install style-loader css-loader --save-dev
  1. style-loader : Injects CSS into the page.  
  2. css-loader : Lets Webpack understand CSS import statements.  
import the CSS in JavaScript 
index.js 
import './styles.css';  // Importing CSS
import './sum.js';
import './product.js';

Update Webpack Config 

Modify webpack.config.js to add a rule for CSS files:  

Rebuild the Project 

npm run build
This will inject the CSS dynamically when bundle.js is loaded.

Open in Browser 

- Open dist/index.html  
- The background should now be light blue🎉  

index.html file missing from dist? 😉

By default, Webpack does not generate an index.html file automatically. It only creates bundle.js. To generate an index.html file inside dist/, you need to use the html-webpack-plugin

How to Generate index.html Automatically

Install html-webpack-plugin:

npm install html-webpack-plugin --save-dev

Update webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './index.js', 
    output: {
        filename: 'bundle.js', 
        path: path.resolve(__dirname, 'dist') 
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.css$/,  // Apply this rule to .css files
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html',  // Use our own template
            filename: 'index.html'         // Output file
        })
    ]
}; 








Comments

Popular posts from this blog

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

React & State Management: All Concepts

React: Communication between components