Lesson 33-Webpack Basics

Webpack is a module bundler for modern JavaScript applications. It bundles modules and their dependencies into one or more bundles for browser execution. The core concepts of Webpack include Entry, Output, Loader, Plugin, Mode, and support for different environments and browser compatibility.

Entry

The entry point is the first module Webpack uses to start building. It can be a string (pointing to a single file), an object, or an array (pointing to multiple files).

// webpack.config.js
module.exports = {
  entry: './src/index.js',
};

Output

The output configuration determines the name, path, and format of the output files.

// webpack.config.js
module.exports = {
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

Loader

Loaders enable Webpack to process non-JavaScript files (e.g., CSS, images). A loader is essentially a function that takes a source file as input and returns the transformed result.

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

Plugin

Plugins are Webpack’s extension points, used for complex tasks like cleaning the output directory, optimizing code, or injecting HTML.

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
};

Mode

Webpack supports two modes: development and production, each with default optimization settings.

// webpack.config.js
module.exports = {
  mode: 'production',
};

Browser Compatibility

Webpack can use tools like Babel to transpile modern JavaScript syntax for compatibility with older browsers.

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  },
};

Environment Variables

Webpack supports reading environment variables, which is useful for multi-environment deployments.

// webpack.config.js
const env = process.env.NODE_ENV;

module.exports = {
  // Configure settings based on environment variables
};

Let’s analyze the application of these concepts with a simple Webpack project:

// src/index.js
import './styles.css';
console.log('Hello Webpack!');

// src/styles.css
body {
  background-color: #f0f0f0;
}
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
  mode: 'development',
};

Complete Example

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');

module.exports = {
  // Mode: development or production
  mode: process.env.NODE_ENV || 'development',

  // Entry
  entry: {
    app: './src/index.js',
  },

  // Output
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/',
  },

  // Modules and Loaders
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: ['@babel/plugin-transform-runtime'],
          },
        },
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader',
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        type: 'asset/resource',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
      },
    ],
  },

  // Plugins
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      inject: 'body',
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
    }),
  ],

  // Browser Compatibility
  target: ['web', 'es5'],
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components'),
    },
  },

  // Environment Variables
  env: {
    development: {
      API_URL: 'http://localhost:3000/api',
    },
    production: {
      API_URL: 'https://api.example.com',
    },
  },

  // Development Server
  devServer: {
    static: path.join(__dirname, 'dist'),
    compress: true,
    port: 3000,
    hot: true,
    historyApiFallback: true,
    proxy: {
      '/api': {
        target: 'http://localhost:4000',
        changeOrigin: true,
      },
    },
  },

  // Optimization Configuration
  optimization: {
    minimize: process.env.NODE_ENV === 'production',
    splitChunks: {
      chunks: 'all',
    },
    runtimeChunk: 'single',
  },

  // Performance Configuration
  performance: {
    hints: false,
  },
};
  • Mode: Sets mode to development or production based on process.env.NODE_ENV.
  • Entry: Defines the entry file as ./src/index.js.
  • Output: Configures the output filename and path.
  • Modules and Loaders:
  • babel-loader: Transpiles ES6+ and JSX code.
  • ts-loader: Handles TypeScript files.
  • css-loader, postcss-loader, sass-loader: Processes CSS and SCSS files.
  • asset/resource: Handles images and font files.
  • Plugins:
  • CleanWebpackPlugin: Cleans the output directory.
  • HtmlWebpackPlugin: Generates an HTML file.
  • MiniCssExtractPlugin: Extracts CSS into separate files.
  • DefinePlugin: Defines environment variables.
  • Browser Compatibility: Targets web and es5.
  • Environment Variables: Sets API_URL based on the environment.
  • Development Server: Configures the dev server with proxy, port, and hot reloading.
  • Optimization: Enables code splitting and minimization in production.
  • Performance: Disables performance hints.
Share your love