Skip to main content

Module 24: Build Tools and Bundlers

Master build tools and bundlers for TypeScript projects including Webpack, Vite, esbuild, and Rollup.


1. TypeScript Compiler (tsc)

# Compile single file
tsc index.ts

# Watch mode
tsc --watch

# Build project
tsc --build

# Incremental build
tsc --incremental
// tsconfig.json
{
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"incremental": true
}
}

2. Webpack with TypeScript

npm install --save-dev webpack webpack-cli ts-loader
// webpack.config.js
const path = require("path");

module.exports = {
entry: "./src/index.ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/
}
]
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
}
};

3. Vite with TypeScript

npm create vite@latest my-app -- --template react-ts
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
plugins: [react()],
build: {
outDir: "dist",
sourcemap: true
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
}
}
});

4. esbuild

npm install --save-dev esbuild
// build.js
const esbuild = require("esbuild");

esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
outfile: "dist/bundle.js",
platform: "node",
target: "node16",
sourcemap: true,
minify: true
}).catch(() => process.exit(1));

5. Rollup with TypeScript

npm install --save-dev rollup @rollup/plugin-typescript
// rollup.config.js
import typescript from "@rollup/plugin-typescript";

export default {
input: "src/index.ts",
output: {
file: "dist/bundle.js",
format: "esm",
sourcemap: true
},
plugins: [typescript()]
};

6. Path Aliases

// tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@utils/*": ["src/utils/*"]
}
}
}

7. Environment Variables

// vite-env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_API_KEY: string;
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}

// Usage
const apiUrl = import.meta.env.VITE_API_URL;

8. Code Splitting

// Dynamic imports
async function loadModule() {
const module = await import("./heavyModule");
module.doSomething();
}

// React lazy loading
const Dashboard = React.lazy(() => import("./Dashboard"));

function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
</Suspense>
);
}

9. Tree Shaking

// utils.ts - Use named exports
export function used() {
return "This will be bundled";
}

export function unused() {
return "This will be tree-shaken";
}

// app.ts - Only import what you need
import { used } from "./utils";

10. Production Optimization

// webpack.config.js (production)
module.exports = {
mode: "production",
optimization: {
minimize: true,
splitChunks: {
chunks: "all"
}
}
};

Key Takeaways

tsc for pure TypeScript compilation
Webpack for complex configurations
Vite for fast development
esbuild for ultra-fast builds
Path aliases for cleaner imports
Code splitting for performance


Practice Exercises

Exercise 1: Configure Webpack

Set up a complete Webpack configuration with TypeScript, CSS, and assets.

Exercise 2: Vite Plugin

Create a custom Vite plugin for TypeScript transformation.


Next Steps

In Module 25, we'll explore Linting and Code Quality with ESLint, Prettier, and code quality tools.