创见博客
webpack 五大核心概念
七崽爱吃小饼干2026/09/15阅读 0专栏 webpack 构建指南

webpack 的配置项看似繁多,但本质上都围绕五个核心概念展开:entry(入口)、output(输出)、loader(加载器)、plugin(插件)、mode(模式)。理解了这五个概念,就等于掌握了 webpack 配置的主干。本文逐一讲解它们的职责、常用写法以及彼此之间的关系。

一、Entry:入口

入口(entry) 是 webpack 构建依赖图的起点。webpack 会从入口文件出发,递归地找出所有直接或间接依赖的模块,最终构建出完整的依赖关系图。可以说,没有入口,webpack 就不知道从哪里开始打包。

最简单的单入口写法:

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

entry 也支持对象语法,用于多入口场景:

js
module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js',
  },
};

多入口常用于多页面应用(MPA),每个入口会生成一份独立的依赖图。此外,entry 还支持数组语法,把多个模块合并打包成一个入口:

js
module.exports = {
  entry: ['./src/polyfills.js', './src/index.js'],
};

小贴士:context 配置项可以指定 entry 的解析基准目录,默认是 webpack 启动时的工作目录。

二、Output:输出

输出(output) 决定打包产物写到哪里、叫什么名字。入口定义了「从哪来」,output 定义了「到哪去」。

js
const path = require('path');

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

几个常用字段:

  • path:产物输出的绝对路径,通常是 path.resolve(__dirname, 'dist')。注意它必须是绝对路径。
  • filename:输出文件名。多入口时可用占位符区分,例如 [name].bundle.js,其中 [name] 对应 entry 的 key。
  • clean:每次构建前自动清理 output 目录,避免残留旧文件。
  • publicPath:指定产物在浏览器中引用的公共路径,常用于 CDN 或静态资源分离场景。

配合多入口输出:

js
module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true,
  },
};

其中 [contenthash] 会随文件内容变化,是浏览器长久缓存的常用手段。

三、Loader:加载器

webpack 本身只理解 JavaScript 和 JSON。Loader 的作用就是把其他类型的文件「翻译」成 webpack 能处理的模块——CSS、图片、字体、TypeScript 等都靠它。

Loader 配置在 module.rules 中,通过 test 匹配文件,通过 use 指定处理链:

js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        type: 'asset/resource',
      },
    ],
  },
};

理解 loader 最关键的一点是执行顺序:use 数组中的 loader **从右到左(从后到前)**依次执行。以上面的 CSS 为例,实际是先用 css-loader 解析 CSS 文件中的 @import 和 url(),再用 style-loader 把样式注入到页面中。

常用 loader 举例:

Loader作用
babel-loader把 ES6+ 语法转译为向后兼容的 JS
css-loader / style-loader解析 CSS、注入样式
sass-loader / less-loader编译 Sass / Less
ts-loader编译 TypeScript
file-loader / url-loader处理文件资源(webpack 5 推荐用 asset modules)

每个 loader 还可以通过对象语法传入 option:

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

四、Plugin:插件

如果说 loader 负责「转换模块」,那么 Plugin 负责的是「扩展 webpack 本身的构建能力」。它可以在构建生命周期的各个阶段挂载钩子,做 loader 做不到的事情,比如生成 HTML、抽离 CSS、压缩代码、定义全局变量、分析打包体积等。

使用插件一般分两步:require 引入,然后在 plugins 数组中 new 一个实例:

js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { DefinePlugin } = require('webpack');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
    new DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
  ],
};

常用插件举例:

Plugin作用
HtmlWebpackPlugin自动生成 HTML 并注入打包产物
MiniCssExtractPlugin把 CSS 抽离成独立文件
CopyWebpackPlugin拷贝静态资源
DefinePlugin定义编译期全局常量
BundleAnalyzerPlugin可视化分析打包体积

Loader 与 Plugin 的区别:loader 面向「文件/模块」,是一个转换函数,运行在模块加载阶段;plugin 面向「整个构建流程」,基于钩子机制,能力更强、范围更广。

五、Mode:模式

Mode 用于告诉 webpack 当前是开发还是生产环境,从而自动启用对应的内置优化:

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

三种取值:

  • development:开启便于调试的能力,如更快的构建、可读的模块名、开发期 Source Map,不做代码压缩。
  • production(默认):开启 Tree Shaking、代码压缩、作用域提升(Scope Hoisting)等优化,产物更小。
  • none:不启用任何默认优化,所有行为完全由配置决定。

也可以通过命令行或 npm scripts 传入:

json
{
  "scripts": {
    "dev": "webpack serve --mode development",
    "build": "webpack --mode production"
  }
}

从 webpack 4 起,mode 是必填项(未显式指定时会给出警告)。合理使用 mode 能省去大量手工优化配置。

五大概念一览

概念职责关键配置
Entry构建依赖图的起点entry
Output决定产物的位置与命名output
Loader把非 JS/JSON 资源转换为模块module.rules
Plugin扩展构建流程、执行更复杂的任务plugins
Mode启用对应环境的内置优化mode

小结

一个完整的 webpack 配置,基本就是这五大概念的组合:从 entry 进入,经 loader 转换各类资源,由 plugin 扩展构建能力,最终按 output 的规则输出,而 mode 则决定整体优化的档位。把这五点记牢,再复杂的配置也能拆解成清晰的结构。

此外,webpack 还有 module(模块)、chunk(代码块)、bundle(产物包) 等延伸概念,它们描述的是打包过程中的粒度与产物形态,后续可以单独展开。

评论
0/100