Module Bundlers
Learn to use module bundlers like Webpack and Vite for efficient JavaScript development. This is a foundational concept in programming and web interactivity that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world JavaScript experience. Take your time with each section and practice the examples
Webpack Configuration
Webpack is a powerful module bundler that transforms and bundles JavaScript modules for the browser.. This is an essential concept that every JavaScript developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Basic Webpack Setup
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babelloader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
};Vite Configuration
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
outDir: 'dist',
sourcemap: true
},
server: {
port: 3000,
open: true
}
});Code Splitting
// Dynamic imports for code splitting
import { lazy } from 'react';
const loadModule = async () => {
const module = await import('./heavy-module.js');
return module.default;
};
// Webpack code splitting
const HomePage = lazy(() => import('./pages/Home'));
const AboutPage = lazy(() => import('./pages/About'));Asset Optimization
// webpack.config.js - Asset optimization
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
]
};Mini-Project: Custom Build Tool
// Simple build tool
const fs = require('fs');
const path = require('path');
class SimpleBundler {
constructor(config) {
this.config = config;
this.modules = new Map();
}
bundle(entry) {
const module = this.loadModule(entry);
return this.generateBundle(module);
}
loadModule(filePath) {
if (this.modules.has(filePath)) {
return this.modules.get(filePath);
}
const content = fs.readFileSync(filePath, 'utf8');
const module = {
id: filePath,
content: this.transformModule(content),
dependencies: this.extractDependencies(content)
};
this.modules.set(filePath, module);
module.dependencies.forEach(dep => {
this.loadModule(dep);
});
return module;
}
transformModule(content) {
// Simple transformation - replace require with module system
return content.replace(/require\(['"]([^'"]+)['"]\)/g, (match, dep) => {
return `__require__('${dep}')`;
});
}
extractDependencies(content) {
const deps = [];
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
let match;
while ((match = requireRegex.exec(content)) !== null) {
deps.push(match[1]);
}
return deps;
}
generateBundle(entryModule) {
let bundle = `(function(modules) {
function __require__(id) {
const module = { exports: {} };
modules[id](module, module.exports, __require__);
return module.exports;
}
return __require__('${entryModule.id}');
})({`;
this.modules.forEach((module, id) => {
bundle += `'${id}': function(module, exports, require) {
${module.content}
},
`;
});
bundle += '});';
return bundle;
}
}