很多前端新手,一听到构建工具就头大,webpack、Vite、ESBuild、rollup、parcel,这么多工具,到底学哪个?怎么学?今天写一篇前端构建的入门指南,从最基础的概念讲起,到主流工具的使用,再到新一代构建工具的原理,帮你从零开始搞懂前端构建。

先说说为什么需要前端构建工具。在很久以前,前端是很简单的,就是写HTML、CSS、JavaScript,然后直接在浏览器里打开,不需要任何构建工具。但随着前端的发展,项目越来越复杂,代码越来越多,我们需要用各种新的技术,比如ES6+、TypeScript、JSX、Sass、Less等,但浏览器不直接支持这些技术,需要转换成浏览器能识别的JavaScript、CSS。

而且,我们还需要做很多优化,比如压缩代码、合并文件、去除未使用的代码、添加文件哈希(用于缓存)、处理图片和字体等资源。这些工作,如果手动做,会非常麻烦,而且容易出错。所以,我们需要构建工具来帮我们做这些事情。

前端构建工具,就是帮我们把源代码转换成可以在浏览器中运行的、优化过的代码的工具。它是前端工程化的核心,也是每个前端开发者必须掌握的技能。

今天,我就从最基础的概念讲起,带大家从零开始学习前端构建。

一、前端构建的基本概念

在说具体的工具之前,先搞清楚几个基本概念。

1. 模块(Module)

模块,就是一个独立的、可复用的代码单元。在JavaScript中,一个模块通常就是一个文件,它可以导出一些变量、函数、类,供其他模块使用;也可以导入其他模块导出的内容。

模块化的好处是:代码可以复用,可以按需加载,可以更好地组织代码结构,避免命名冲突。

JavaScript的模块规范有好几种,比如CommonJS(Node.js用的,用require和module.exports)、ES Module(ES6引入的,用import和export,现在是主流)、AMD、CMD等。现在的前端项目,一般都用ES Module。

2. 打包(Bundle)

打包,就是把多个模块和它们的依赖,合并成一个或多个文件,供浏览器使用。因为浏览器虽然现在支持ES Module了,但如果模块很多,一个个加载会很慢,而且有兼容性问题。所以,我们一般会把所有模块打包成一个或几个文件,这样浏览器只需要加载少数几个文件,速度更快。

打包的过程,一般包括:解析入口文件,分析依赖关系,把所有依赖的模块都找出来,然后做一些转换(比如把ES6转换成ES5,把TypeScript转换成JavaScript),然后合并成一个或多个文件,最后做一些优化(比如压缩、去重等)。

3. 入口(Entry)

入口,就是打包的起点文件。构建工具从入口文件开始,分析它的依赖,然后把所有依赖的模块都打包进来。一个项目可以有一个入口,也可以有多个入口(比如多页应用,每个页面一个入口)。

4. 输出(Output)

输出,就是打包之后的文件放在哪里,叫什么名字。一般会配置输出的目录、文件名、公共路径等。

5. Loader(加载器)

Loader,是用来转换文件的。因为构建工具默认只能处理JavaScript文件,如果要处理其他类型的文件(比如CSS、图片、字体、TypeScript、JSX等),就需要用对应的Loader来转换。

比如,用css-loader处理CSS文件,用babel-loader处理ES6+的JavaScript,用ts-loader处理TypeScript,用file-loader处理图片和字体等。

Loader的特点是:它是一个函数,接收文件内容,返回转换后的内容。Loader可以链式调用,一个文件可以经过多个Loader的转换,最后得到想要的结果。

6. Plugin(插件)

Plugin,是用来扩展构建工具功能的。Loader只能用来转换文件,而Plugin可以做更多的事情,比如压缩代码、提取CSS、生成HTML文件、清理输出目录、复制文件等。

Plugin的特点是:它是一个对象,有一个apply方法,构建工具在运行的时候会调用这个方法,把一些钩子(hook)传给Plugin,Plugin可以在这些钩子里做一些事情。

7. Dev Server(开发服务器)

Dev Server,是开发环境用的本地服务器。它可以在本地启动一个服务器,让我们可以通过http://localhost来访问我们的页面,而不是直接用file://协议打开。而且,它支持热更新(HMR,Hot Module Replacement),当我们修改代码的时候,页面会自动更新,不需要手动刷新,开发体验很好。

8. 代码分割(Code Splitting)

代码分割,就是把代码分成多个块(chunk),而不是打包成一个大文件。这样做的好处是:可以按需加载,需要的时候才加载对应的代码,减少首屏加载的时间;可以更好地利用浏览器缓存,公共的代码单独打包,不会因为业务代码变化而重新加载。

常见的代码分割方式有:按入口分割、按动态import分割、按公共依赖分割(比如把react、vue这些第三方库单独打包)。

二、主流构建工具介绍

搞清楚了基本概念,再说说现在主流的构建工具。

1. webpack

webpack是目前最主流的前端构建工具,功能非常强大,生态非常完善,几乎所有的前端项目都在用webpack。

webpack的特点:

  • 功能强大,支持各种前端技术和框架
  • 生态完善,有大量的Loader和Plugin
  • 配置灵活,可以满足各种复杂的需求
  • 社区活跃,文档完善,遇到问题容易找到解决方案

webpack的缺点:

  • 配置比较复杂,新手入门门槛高
  • 构建速度相对较慢,尤其是大项目,启动dev server和打包都比较慢
  • 概念比较多,学习曲线陡峭

虽然webpack有一些缺点,但它依然是目前最主流、最强大的前端构建工具,大部分公司的项目都在用webpack。所以,webpack是前端开发者必须掌握的构建工具。

2. Vite

Vite是尤雨溪(Vue.js的作者)在2020年推出的新一代前端构建工具,主打"快"。Vite在开发环境下,利用浏览器原生的ES Module,不需要打包,启动速度非常快,热更新也很快。在生产环境下,Vite用rollup来打包,也很快。

Vite的特点:

  • 开发环境启动极快,因为不需要打包,利用浏览器原生ES Module
  • 热更新极快,修改代码之后几乎是即时更新
  • 配置简单,开箱即用,不需要太多配置
  • 对Vue支持很好,也支持React、Preact等框架
  • 生产环境用rollup打包,构建速度快,产物体积小

Vite的缺点:

  • 比较新,生态不如webpack完善,一些特殊的需求可能没有对应的插件
  • 开发环境和生产环境的构建工具不一样(开发用esbuild,生产用rollup),可能会有一些不一致的问题
  • 对一些老项目的兼容性不如webpack

Vite是新一代构建工具的代表,发展非常快,现在已经有很多项目在用Vite了,尤其是新项目。如果你在做新项目,尤其是Vue或者React的项目,非常推荐试试Vite,开发体验真的很好。

3. ESBuild

ESBuild是一个用Go语言写的JavaScript打包器,主打"极快"。它的构建速度比webpack快几十倍甚至上百倍,因为它是用Go写的,多线程并行处理,而且做了很多优化。

ESBuild的特点:

  • 极快,构建速度比webpack快几十倍
  • 支持JavaScript、TypeScript、JSX等
  • 可以做打包、压缩、转换等
  • 可以作为其他构建工具的底层(比如Vite在开发环境下就用了ESBuild来做转换)

ESBuild的缺点:

  • 功能相对简单,不如webpack强大
  • 生态不如webpack完善,插件比较少
  • 不支持HMR(热更新)
  • 不支持代码分割等高级功能(至少目前还不完善)

ESBuild一般不单独作为完整的构建工具使用,而是作为其他构建工具的一部分,或者用来做一些简单的打包和转换。但它的速度真的很快,代表了未来构建工具的发展方向。

4. Rollup

Rollup是一个JavaScript模块打包器,主打"小而美"。它主要用来打包JavaScript库,因为它支持Tree Shaking(去除未使用的代码),打包出来的产物很小,很干净。

Rollup的特点:

  • 支持ES Module,Tree Shaking效果好
  • 打包出来的产物干净、小
  • 配置简单
  • 适合打包JavaScript库

Rollup的缺点:

  • 功能不如webpack强大
  • 对应用的支持不如webpack(比如代码分割、HMR等)
  • 生态不如webpack完善

Rollup主要用来打包JavaScript库,很多知名的库(比如Vue、React、D3等)都是用Rollup打包的。Vite在生产环境下也是用Rollup来打包的。

5. Parcel

Parcel是一个零配置的前端打包工具,主打"简单"。它不需要任何配置,开箱即用,支持各种前端技术,自动处理各种文件类型。

Parcel的特点:

  • 零配置,开箱即用
  • 支持各种前端技术
  • 构建速度快(用了多核并行处理)
  • 支持HMR

Parcel的缺点:

  • 自定义程度不如webpack高
  • 生态不如webpack完善
  • 一些复杂的需求可能无法满足

Parcel适合一些简单的项目,或者不想花时间配置的项目。但对于复杂的企业级项目,一般还是用webpack。

三、怎么选?

这么多构建工具,到底选哪个?我的建议是:

1. 如果你是新手,先学webpack

webpack是目前最主流的构建工具,大部分公司的项目都在用。先把webpack学会了,找工作、做项目都能用得上。而且,学会了webpack,再学其他构建工具就很容易了,因为基本概念都是相通的。

2. 如果你在做新项目,尤其是Vue/React项目,推荐用Vite

Vite的开发体验真的很好,启动快,热更新快,配置简单。如果是新项目,尤其是Vue或者React的项目,非常推荐用Vite。现在Vite已经很成熟了,大部分需求都能满足。

3. 如果你在打包JavaScript库,用Rollup

Rollup适合打包JavaScript库,Tree Shaking效果好,产物干净。如果你在写一个开源库,推荐用Rollup。

4. 如果你想要极快的构建速度,可以关注ESBuild

ESBuild虽然功能还不够完善,但它的速度真的很快,代表了未来的方向。可以关注它的发展,或者在一些场景下使用它(比如作为转换工具,或者和其他工具配合使用)。

5. 如果你不想配置,做简单的项目,可以用Parcel

Parcel零配置,开箱即用,适合简单的项目,或者新手学习。

四、webpack入门实战

说了这么多,下面带大家做一个简单的webpack入门实战,从零开始搭建一个简单的webpack项目。

第一步:初始化项目

新建一个目录,然后在目录里执行:

npm init -y

这会生成一个package.json文件。

第二步:安装webpack

npm install webpack webpack-cli --save-dev

webpack是核心包,webpack-cli是命令行工具,用来在命令行里运行webpack。

第三步:创建目录和文件

创建以下目录和文件:

- src
  - index.js
  - utils.js
- index.html
- webpack.config.js

src/index.js是入口文件,内容如下:

import { sayHello } from './utils.js';

sayHello('World');

src/utils.js是工具函数,内容如下:

export function sayHello(name) {
  console.log(`Hello, ${name}!`);
}

index.html是HTML模板,内容如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Webpack Demo</title>
</head>
<body>
  <script src="dist/main.js"></script>
</body>
</html>

webpack.config.js是webpack的配置文件,内容如下:

const path = require('path');

module.exports = {
  entry: './src/index.js', // 入口文件
  output: {
    path: path.resolve(__dirname, 'dist'), // 输出目录
    filename: 'main.js', // 输出文件名
  },
  mode: 'development', // 模式:development或production
};

第四步:运行打包

在package.json里添加一个script:

{
  "scripts": {
    "build": "webpack"
  }
}

然后执行:

npm run build

webpack就会开始打包,打包完成之后,会在dist目录下生成main.js文件。然后在浏览器里打开index.html,打开控制台,就能看到"Hello, World!"的输出了。

第五步:添加Loader,处理CSS

现在我们的项目只能处理JavaScript,如果要处理CSS,就需要添加Loader。

先安装css-loader和style-loader:

npm install css-loader style-loader --save-dev

css-loader用来处理CSS文件,解析CSS中的import和url;style-loader用来把CSS插入到HTML的style标签里。

然后在webpack.config.js里添加配置:

module.exports = {
  // ... 其他配置
  module: {
    rules: [
      {
        test: /\.css$/, // 匹配.css文件
        use: ['style-loader', 'css-loader'], // 用这两个Loader处理
      },
    ],
  },
};

注意,Loader的执行顺序是从右到左的,所以css-loader在右边,先执行,然后style-loader在左边,后执行。

然后在src目录下创建一个style.css文件:

body {
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
}

然后在index.js里导入:

import './style.css';

然后重新打包,刷新页面,就能看到背景色变了,CSS生效了。

第六步:添加Plugin,自动生成HTML

现在我们的HTML文件是手动写的,而且需要手动引入打包后的JS文件。我们可以用html-webpack-plugin来自动生成HTML文件,并自动引入打包后的JS。

先安装:

npm install html-webpack-plugin --save-dev

然后在webpack.config.js里配置:

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

module.exports = {
  // ... 其他配置
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html', // 模板文件
    }),
  ],
};

然后把index.html里的script标签删掉,因为html-webpack-plugin会自动添加。然后重新打包,dist目录下会自动生成index.html,并且自动引入了main.js。

第七步:配置Dev Server

webpack-dev-server是一个开发服务器,支持热更新,开发体验很好。

先安装:

npm install webpack-dev-server --save-dev

然后在webpack.config.js里配置:

module.exports = {
  // ... 其他配置
  devServer: {
    static: './dist', // 静态文件目录
    hot: true, // 开启热更新
    port: 3000, // 端口
  },
};

然后在package.json里添加一个script:

{
  "scripts": {
    "build": "webpack",
    "dev": "webpack serve"
  }
}

然后执行:

npm run dev

webpack-dev-server就会启动,在浏览器里打开http://localhost:3000,就能看到页面了。而且,修改代码之后,页面会自动更新,不需要手动刷新,开发体验很好。

到这里,一个简单的webpack项目就搭建完成了。当然,webpack还有很多高级功能,比如代码分割、Tree Shaking、缓存、多入口、环境变量等,这里就不一一展开了。大家可以在实际项目中慢慢学习和探索。

五、新一代构建工具的原理

最后,简单说说新一代构建工具(比如Vite、ESBuild)为什么这么快,它们的原理是什么。

传统的构建工具(比如webpack),在开发环境下,需要先把所有模块都打包好,然后才能启动dev server。项目越大,打包时间越长,启动越慢。而且,修改代码之后,需要重新打包相关的模块,热更新也比较慢。

而Vite在开发环境下,利用了浏览器原生的ES Module,不需要打包。浏览器请求哪个模块,Vite就实时转换哪个模块,然后返回给浏览器。这样,启动的时候不需要打包,几乎是秒开。修改代码之后,只需要重新转换修改的那个模块,热更新也很快。

而且,Vite用ESBuild来做模块的转换(比如把TypeScript、JSX转换成JavaScript),ESBuild是用Go写的,多线程并行处理,速度比用JavaScript写的babel快几十倍。所以,Vite的转换速度也很快。

在生产环境下,Vite用Rollup来打包,因为Rollup的Tree Shaking效果好,产物体积小,而且Rollup也比较快。

ESBuild之所以这么快,主要有几个原因:

  1. 用Go语言写的,编译成机器码,执行速度快,比JavaScript快很多
  2. 多线程并行处理,充分利用多核CPU
  3. 自己写了词法分析、语法分析、代码生成等,没有用第三方库,做了很多优化
  4. 内存布局优化,缓存命中率高

新一代构建工具,代表了前端构建的未来。随着它们的不断发展和完善,可能会逐渐取代webpack,成为主流。当然,webpack也在不断优化,比如webpack 5也做了很多性能优化,启动速度和构建速度都提升了不少。

六、学习建议

最后,给想学习前端构建的朋友一些建议。

1. 先搞清楚基本概念

在学具体的工具之前,先把基本概念搞清楚,比如模块、打包、入口、输出、Loader、Plugin、Dev Server、代码分割等。这些概念是通用的,搞清楚了,学任何构建工具都很快。

2. 从webpack开始学

webpack是目前最主流的构建工具,先把webpack学会了,找工作、做项目都能用得上。而且,webpack的概念最完整,学会了webpack,其他工具就很容易了。

3. 多动手,多实践

学习构建工具,光看教程是不够的,一定要多动手,多实践。自己从零开始搭建一个项目,配置各种Loader和Plugin,遇到问题自己查文档、查资料解决。只有亲手做过,才能真正掌握。

4. 关注新一代构建工具

在学好webpack的基础上,也要关注新一代构建工具,比如Vite、ESBuild、Turbopack等。这些工具代表了未来的方向,发展很快,以后可能会成为主流。多了解一些,对自己的发展有好处。

5. 理解原理,不要只会用

不要只停留在"会用"的层面,还要理解背后的原理。比如,webpack的打包原理是什么?HMR的原理是什么?Vite为什么这么快?ESBuild为什么这么快?理解了原理,才能更好地使用工具,遇到问题也能更快地定位和解决。

七、写在最后

前端构建,是前端工程化的核心,也是每个前端开发者必须掌握的技能。虽然一开始学起来可能会觉得复杂、头大,但只要搞清楚了基本概念,多动手实践,慢慢就会觉得其实也没那么难。

而且,前端构建工具在不断发展,从webpack到Vite、ESBuild,越来越快,越来越简单,开发体验越来越好。作为前端开发者,我们要不断学习,跟上技术的发展,才能不被淘汰。

希望这篇入门指南,能帮到正在学习前端构建的你。如果有什么问题,欢迎在评论区交流。