Webpack 核心概念

理解 Webpack 的核心概念是掌握 Webpack 的基础。本章将详细介绍 Entry、Output、Loader、Plugin 和 Mode 这五个核心概念。


📋 核心概念概览

Webpack 有五个核心概念:

  1. Entry(入口) - 告诉 Webpack 从哪里开始
  2. Output(输出) - 告诉 Webpack 在哪里输出结果
  3. Loader(加载器) - 告诉 Webpack 如何处理非 JS 文件
  4. Plugin(插件) - 执行更广泛的任务
  5. Mode(模式) - 指定构建模式

1. Entry(入口)

Entry 指定 Webpack 从哪个文件开始构建依赖图。

单入口(字符串)

module.exports = {
  entry: './src/index.js'
}

适用场景:单页面应用(SPA)

多入口(对象)

module.exports = {
  entry: {
    main: './src/index.js',
    vendor: './src/vendor.js'
  }
}

适用场景:需要分离第三方库代码

动态入口(函数)

module.exports = {
  entry: () => './src/index.js'
}

适用场景:根据条件动态决定入口

入口配置示例

// webpack.config.js
module.exports = {
  // 单入口
  entry: './src/index.js',
  
  // 或者多入口
  entry: {
    app: './src/app.js',
    admin: './src/admin.js'
  }
}

2. Output(输出)

Output 指定打包后的文件输出位置和命名规则。

基础配置

const path = require('path')
 
module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
}

多入口输出

module.exports = {
  entry: {
    main: './src/index.js',
    vendor: './src/vendor.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js'  // main.bundle.js, vendor.bundle.js
  }
}

使用 Hash(缓存优化)

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    chunkFilename: '[name].[chunkhash].js'
  }
}

Hash 类型说明

  • [hash]:整个项目的 hash(所有文件共享)
  • [chunkhash]:chunk 的 hash(每个 chunk 不同)
  • [contenthash]:内容的 hash(推荐,只有内容变化才改变)

完整 Output 配置

const path = require('path')
 
module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name].[contenthash:8].js',
    chunkFilename: 'js/[name].[contenthash:8].chunk.js',
    publicPath: '/',  // 公共路径
    clean: true,      // 清理输出目录
    assetModuleFilename: 'assets/[hash][ext]'  // 资源文件命名
  }
}

3. Loader(加载器)

Loader 用于转换非 JavaScript 文件,让 Webpack 能够处理各种类型的资源。

Loader 工作原理

源文件 → Loader1 → Loader2 → Loader3 → 最终结果

基础语法

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,  // 匹配文件
        use: ['style-loader', 'css-loader']  // 使用的 Loader
      }
    ]
  }
}

常用 Loader

CSS Loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',  // 将 CSS 注入到 DOM
          'css-loader'     // 解析 CSS 文件
        ]
      }
    ]
  }
}

Babel Loader(转译 JavaScript)

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
}

文件资源 Loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif|svg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'images/[hash][ext]'
        }
      }
    ]
  }
}

Loader 执行顺序

Loader 从右到左(或从下到上)执行:

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          'style-loader',   // 3. 最后执行
          'css-loader',     // 2. 然后执行
          'sass-loader'     // 1. 最先执行
        ]
      }
    ]
  }
}

执行流程

  1. sass-loader 将 SCSS 转换为 CSS
  2. css-loader 解析 CSS 中的 @importurl()
  3. style-loader 将 CSS 注入到 DOM

4. Plugin(插件)

Plugin 用于执行更广泛的任务,如打包优化、资源管理、环境变量注入等。

Plugin 工作原理

Plugin 是一个类,通过 apply 方法注册到 Webpack 的生命周期钩子中。

class MyPlugin {
  apply(compiler) {
    compiler.hooks.done.tap('MyPlugin', (stats) => {
      console.log('构建完成!')
    })
  }
}

常用 Plugin

HtmlWebpackPlugin(生成 HTML)

const HtmlWebpackPlugin = require('html-webpack-plugin')
 
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true
      }
    })
  ]
}

CleanWebpackPlugin(清理输出目录)

const { CleanWebpackPlugin } = require('clean-webpack-plugin')
 
module.exports = {
  plugins: [
    new CleanWebpackPlugin()
  ]
}

DefinePlugin(定义环境变量)

const webpack = require('webpack')
 
module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production'),
      'process.env.API_URL': JSON.stringify('https://api.example.com')
    })
  ]
}

5. Mode(模式)

Mode 指定构建模式,影响 Webpack 的优化行为。

三种模式

module.exports = {
  mode: 'development'  // 或 'production' 或 'none'
}

Development 模式

module.exports = {
  mode: 'development'
}

特点

  • 代码不会被压缩
  • 包含详细的错误信息
  • 构建速度快
  • 启用 Source Map

Production 模式

module.exports = {
  mode: 'production'
}

特点

  • 代码会被压缩和优化
  • 移除未使用的代码(Tree Shaking)
  • 构建速度较慢
  • 生成的文件更小

None 模式

module.exports = {
  mode: 'none'
}

特点

  • 不启用任何默认优化
  • 完全手动控制

完整配置示例

结合所有核心概念的完整配置:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
 
module.exports = {
  // 1. Entry(入口)
  entry: './src/index.js',
  
  // 2. Output(输出)
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[contenthash].js',
    clean: true
  },
  
  // 3. Mode(模式)
  mode: 'development',
  
  // 4. Loader(加载器)
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  
  // 5. Plugin(插件)
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
}

核心概念关系图

Entry(入口)
    ↓
[分析依赖]
    ↓
Loader(转换文件)
    ↓
[打包模块]
    ↓
Plugin(优化处理)
    ↓
Output(输出)

总结

  • Entry:告诉 Webpack 从哪里开始
  • Output:告诉 Webpack 输出到哪里
  • Loader:转换非 JS 文件
  • Plugin:执行更广泛的任务
  • Mode:指定构建模式

理解这五个核心概念后,你就可以开始配置 Webpack 了!


下一步


Webpack 核心概念 Entry Output Loader Plugin Mode