Skip to content
On this page

Webpack 基础概念

Webpack 是一个模块打包器,它将项目视为一个整体,通过分析模块之间的依赖关系,最终生成一个或多个静态资源。理解 Webpack 的核心概念是掌握它的关键。

核心概念

1. 入口(Entry)

入口起点指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。

javascript
// 单入口
module.exports = {
  entry: './src/index.js'
};

// 多入口
module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js',
    contact: './src/contact.js'
  }
};

2. 输出(Output)

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。

javascript
const path = require('path');

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

// 多入口多输出
module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js'  // [name] 会被替换为入口名称
  }
};

3. 加载器(Loaders)

Webpack 本身只能处理 JavaScript 和 JSON 文件,加载器让 webpack 能够处理其他类型的文件,并将它们转换为有效模块。

javascript
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',  // 第二个执行
          'css-loader'     // 第一个执行
        ]
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',  // Webpack 5 的新方式
        generator: {
          filename: 'images/[name].[hash][ext]'
        }
      }
    ]
  }
};

4. 插件(Plugins)

插件用于执行范围更广的任务,包括打包优化、资源管理、注入环境变量等。

javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  plugins: [
    new CleanWebpackPlugin(),  // 清理输出目录
    new HtmlWebpackPlugin({
      title: 'My App',
      template: './src/index.html'
    })
  ]
};

5. 模式(Mode)

通过设置 mode 参数,可以启用相应环境的内置优化。

javascript
module.exports = {
  mode: 'development'  // 'development', 'production', or 'none'
};

模块(Modules)

在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块。

每个模块都对其他模块可用的功能有所贡献,这些功能被称为模块的导出(exports)。

javascript
// math.js - 模块定义
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

// index.js - 模块使用
import { add, subtract } from './math.js';

console.log(add(2, 3));      // 5
console.log(subtract(5, 2)); // 3

依赖图(Dependency Graph)

每当一个文件依赖于另一个文件时,webpack 就会将文件视为直接依赖关系。这使得 webpack 可以接收非代码资源,如 images 或 web fonts,处理它们,然后将它们作为依赖项图的一部分。

javascript
// index.js
import './style.css';        // 依赖关系
import Icon from './icon.png';  // 依赖关系

function component() {
  const element = document.createElement('div');

  // 将图像添加到我们现有的 div 中
  const myIcon = new Image();
  myIcon.src = Icon;

  element.appendChild(myIcon);

  return element;
}

document.body.appendChild(component());

配置文件(Configuration)

webpack 的配置文件是一个 JavaScript 文件,它导出一个对象。这个对象包含 webpack 所需的各种配置选项。

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

module.exports = {
  // 入口点
  entry: './src/index.js',
  
  // 输出配置
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true  // Webpack 5 新特性,清理输出目录
  },
  
  // 模块规则
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  
  // 插件
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  
  // 开发工具
  devtool: 'inline-source-map',
  
  // 开发服务器配置
  devServer: {
    static: './dist',
    hot: true
  }
};

构建目标(Targets)

可以配置 webpack 构建针对不同环境的代码:

javascript
module.exports = {
  target: 'web',        // 默认,浏览器环境
  // target: 'node',    // Node.js 环境
  // target: 'webworker', // Web Worker 环境
};

小结

Webpack 的核心概念包括入口、输出、加载器、插件、模式等。理解这些概念有助于更好地配置和使用 Webpack。通过这些概念的组合,Webpack 可以处理各种类型的资源,并将其打包成适合生产环境的代码。