前言

本篇文章旨在总结前端常见的构建工具,构建工具是前端工程化中的重要的组成部分。

在实际项目中,我们初始化项目,一般是使用脚手架命令一键生成的,比如说使用 create-vue 初始化 vue 项目的时候,就会默认使用 vite 进行打包,同理使用 vue-cli 的时候就是默认使用webpack进行打包(现在vue已经不推荐使用这种方式了)

pnpm create vue@latest

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图

使用脚手架初始化项目简单又方便,很多东西都是现成的,但是这就导致有的时候新手小白不会去认真看打包工具的官网,误以为诸如 webpack 和 vite 等打包工具只能和 vue/ react 等框架绑定使用。

所以我的建议是,可以跟着打包工具的官网,一步一步跟着来详细的学习一下,然后再看你用脚手架初始化的项目,有些东西和配置你才会豁然开朗。

还是需要强调一下,学习一个新的工具,首选的学习资料就是该工具的官网。官网的教程,系统而详细,不要一遇到问题就去百度/博客上搜,得到的结果往往是乱七八糟的。

一、准备工具

1.1 创建仓库

1.1.1 新建 gitee 仓库

我用 gitee 仓库纯粹是因为不方便科学上网,大家也可以使用 github

我的仓库地址是 learn-pack-build 

1.1.2 克隆到本地

把你的项目克隆到本地,并新增 .gitignore 文件。

接下来我们就在这个项目中学习各种打包工具。

1.2 前端构建工具总结

前端的构建工具有很多,随着技术的发展有些已经不是主流使用的了,请参考这篇文章,我们还是主要学习主流用的工具比如 webapck。但是在面试的时候,会问你各种工具的区别,所以还是要学习一下现在已经不常用的构建工具比较好,这样方便理解,比如 grunt 和 gulp。多学习一点总是没错的。

我们把这些打包工具主要分为两类,一类是基于任务的打包工具(grunt 和 gulp),第二类是基于模块的打包工具(webpack、vite、esbuild、roollup、parcel、browserify),这 8 个的基础用法我们都要学习一下,才能够更好的理解。

注意,这些工具我们比较习惯称之为构建工具,而不是打包工具,因为打包工具听起来就只是一个简单的打包功能,但是构建工具有很多其他的功能,比如编译、测试、打包、优化、压缩等。还是称之为构建工具比较好。

二、基于任务的构建工具

对于基于任务的构建工具主要就了解以下两个就行,了解即可,知道它们为什么是基于任务的就行。

2.1 grunt 

Grunt 是一个基于任务的构建工具,通过配置任务列表,实现前端项目的自动化构建和优化。Grunt 的任务通常是串行执行的,但是可以使用一些插件实现并行执行。

Grunt 是一个 JavaScript 任务运行器,它使用配置文件(通常是一个名为 Gruntfile.js 的文件)来定义任务。任务通常是一些插件的集合,用于执行各种操作,如文件的合并、压缩、编译等。Grunt 使用相对较多的配置,因此有些开发者可能觉得其配置较为冗长。

注意这个单词的发音【g ruang t】

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(1)

我们可以跟着 grunt 的官网来学一下到底怎么用,恕我直言,我也没用过这个工具,但是跟着官网一步一步来,是可以很容易打包一个 js 文件的。

详细代码请参看项目的这个文件夹

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(2)

重点是 Gruntfile.js 这个文件,在这个文件中【定义任务】—> 【注册任务】可以使用各种插件,grunt 有很多可以使用的插件,总之我们需要理解 grunt 是基于任务的构建工具。

2.2 gulp

 Gulp 也是一个基于任务的构建工具,通过定义一系列任务,可以实现对前端项目的自动化构建,包括文件的合并、压缩、编译等。Gulp 原生就可以支持任务的串行、并行执行。

Gulp 则是另一个 JavaScript 任务运行器,它更加基于代码,使用流/管道(stream)来定义任务。开发者通过编写 JavaScript 代码来配置任务,这使得任务的定义更加灵活、简洁。Gulp 的流式处理方式通常被认为更加直观和易于理解。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(3)

g ao p​

同样的我们跟着 gulp 的官网一步一步来实现一个简单的 demo。

详细代码请参看项目的这个文件夹

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(4)

2.3 grunt 和 gulp 的区别

Grunt 和 Gulp 是 JavaScript 的构建工具,它们有很多相似之处,但也存在一些区别,主要集中在以下几个方面:

  1. 配置方式

    • Grunt 使用基于配置的方式来定义任务,通常在一个名为 Gruntfile.js 的文件中指定任务和任务的配置。这种方式需要开发者编写较多的配置代码。
    • Gulp 使用基于代码的方式来定义任务,开发者可以编写 JavaScript 代码来配置任务,使用管道(streams)来处理文件。这种方式相对于 Grunt 更加直观和灵活。
  2. API 和插件

    • Grunt 的插件系统相对成熟,拥有大量的插件可供使用,涵盖了很多常见的构建任务,例如文件合并、压缩、编译等。
    • Gulp 也有丰富的插件生态,但由于其基于流的设计,使得编写自定义任务变得更加简单,因此有时候不需要借助插件也可以完成很多任务。
  3. 性能

    • Gulp 的流式处理方式使得任务可以并行执行,因此在处理大量文件时可能会比 Grunt 更快。
    • Grunt 的任务通常是串行执行的,虽然可以通过一些插件实现并行执行,但默认情况下较为常见的是串行执行任务。
  4. 易用性和可读性

    • 由于 Gulp 的代码优先设计,任务的定义相对更加直观和简洁,使得代码更易读、易维护。
    • Grunt 的配置方式可能会显得冗长和繁琐,对于一些开发者来说可能不太友好。

总的来说,Grunt 和 Gulp 在实现自动化构建方面都能很好地胜任,但在使用体验、性能和可读性等方面存在一些差异,开发者可以根据自己的偏好和项目需求选择合适的工具。

好了,基于任务的构建工具就了解 grunt 和 gulp 两个就行。接下来我们要学习一下重头戏,基于模块的构建工具,这个部分我也分为两组。一组是简单的,如 parcel、browserify、roollup、esbuild,一组是较复杂的 webpack 和 vite 

三、简单的基于模块的构建工具

3.1 parcel

Parcel 是一个零配置的前端打包工具,可以自动识别项目中的文件,并进行相应的打包。它支持多种文件类型,支持热更新,并且具有快速的打包速度。

3.1.1 优点

  • 零配置
  • 运行后会启动一个开发服务器,支持热更新
  • 支持自动安装依赖,webpack 开发阶段突然使用安装某个第三方依赖,必须终止开发服务器,parcel 不需要
  • parcel 加载 css 等资源文件无需配置
  • 打包过程时多进程同时工作的,速度快,输出文件会被压缩,样式代码会被单独提取到单个文件中
  • 支持 tree-shaking

3.1.2 缺点

  • 修改文件后和 webpack 一样需要重新构建,重新打包应用程序的整个 bundle,这一点 snowpack 和 vite 做了优化【snowpack 也是一种构建工具,本文没有详细说明】

注意这个零配置,给人的感觉好邪乎,好神奇,有这么好的事?不要怕,一切都是纸老虎

同样的我们跟着 parcel 官网来实现一个简单的 demo,你测试一下会发现确实很快,而且不用任何关于 parcel 的配置文件。

详细代码请参看项目的这个文件夹

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(5)

我个人认为,如果你自己写一个学习的项目,不考虑性能,用这个打包是绝佳的首选,简单好上手,零配置真是强推。

但是如果在实际的项目中,我们就要考虑性能等各种方面,parcel 没有webpack 的社区活跃,功能强大。

parcel 2的官网里面显示也支持插件等,功能比1 强大很多,有兴趣可以试着学习一下(我没有兴趣~~)

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(6)

3.2 browserify

 Browserify 允许在前端使用类似于 Node.js 的 require 语法,将模块化的 JavaScript 文件打包成一个文件,以便在浏览器中使用,它打包后的文件可以直接在html 中引用。

  1. 模块化开发:Browserify 允许开发者使用模块化的方式组织 JavaScript 代码,使得代码更易于维护、重用和测试。通过 require() 来引入模块,可以将代码分割成多个文件,每个文件负责一个特定的功能,有助于降低代码耦合度。

  2. 依赖管理:Browserify 自动处理模块之间的依赖关系,可以将各个模块打包到一个文件中,避免了手动管理依赖关系的繁琐工作。这简化了开发流程,提高了开发效率。

  3. 前端与后端代码共享:由于 Browserify 可以使用类似于 Node.js 的模块系统,在一定程度上实现了前端和后端代码的共享,使得开发者可以更容易地在前端和后端之间共享代码和逻辑,提高了代码复用性和一致性。

  4. 使用 npm 生态系统:Browserify 可以直接使用 npm 上的模块,这意味着您可以利用 npm 生态系统中丰富的第三方模块和工具来加速开发,无需额外的学习成本。

  5. 支持预处理器:除了 JavaScript 模块外,Browserify 还支持预处理器,如通过适当的插件,可以使用 CoffeeScript、TypeScript、Less 等语言,并将其编译成浏览器可执行的 JavaScript 代码。

如果你用过 webpack 等主流的构建工具,你会发现 browserify 有的功能,webpack 也有,因为 browserify 是先提出来的,所以有了webpack 之后就不咋用了。

看出来了,它的核心优势就是前端使用类似于 Node.js 的 require 语法

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(7)

 同样的我们跟着 browserify 的官网实现一个简单的demo,看看怎么回事。

详细代码请参看项目的这个文件夹,在这个demo中也是没有配置文件,只是单纯的使用 browserify 打包了一个 js 文件。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(8)

四、重要的基于模块的构建工具

这一章节会介绍 4 个重要的构建工具,分别是 rollup 、esbuild、webpack、vite,都是我们在开发过程中常用的,这四个构建工具的共同点有

  1. 都是基于模块的构建工具:都用于将多个 JavaScript 模块打包成一个或多个浏览器可执行的文件。它们可以处理不同类型的模块(例如 CommonJS、ES6 模块等)并将它们合并为一个输出文件
  2. 优化和压缩,都支持 tree-shaking:提供了代码优化和压缩的功能,以减少输出文件的大小并提高页面加载速度。它们可以去除未使用的代码(Tree-shaking)、进行代码压缩、合并文件等操作。
  3. 插件系统:Rollup、Webpack 和 Vite 都拥有丰富的插件系统,允许开发者根据需要扩展和定制构建过程。esbuild 本身并没有插件系统,但是它的速度快,可以作为其他工具的插件使用。

4.1 Rollup

Rollup 是一个 JavaScript 模块打包器,专注于打包 JavaScript 库。它能够进行 Tree-shaking,即删除未使用的代码,以减小打包后的文件体积,常用于构建库(library),特别是那些专注于 ES6 模块的库。

4.1.1 优点

  • 代码效率更简洁、效率更高
  • 默认支持 tree-shaking
  • 常用于打包 js 库,如 vue 等,因为打包出来的代码更小,更快

4.1.2 缺点

  • 加载其他类型文件 / 导入 cjs 模块/ 编译 es 新特性,都需要使用插件去完成
  • 不适合开发应用,因为应用一般需要第三方模块,而第三方模块大多使用 commonjs 方式导出成员,「rollup需要用插件才能完成这个功能」
  • 不支持热更新,开发效率低

JavaScript 库是啥?

JavaScript 库通常包含了一系列功能、组件或模块,用于在开发过程中提供特定的功能或解决特定的问题。vue 、react、jquery、lodash 等都属于 javascript库。就是我们使用 npm 命令去安装的都是 js 库。

在我们的项目中很少单独时候 rollup 打包,但是实际上我们常用的构建工具 vite 他的底层逻辑就是使用了 rollup, 所以还是有必要学习一下的。

可以跟着rollup 官网进行学习,rollup 支持配置文件,支持插件,但是不支持热更新。

详细代码请参看项目的这个文件夹。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(9)

如果你在自己学习一个新的技术,也可以是试着使用 rollup 进行打包。不过 rollup 不支持热更新,不如之前说的 parcel 方便。

4.2 esbuild

esbuild 是一个非常快速的 JavaScript 和 TypeScript 构建工具。它以极快的速度执行构建任务,并支持 Tree-shaking,即消除未使用的代码。esbuild 被设计成一个零配置的工具,但也提供了一些配置选项供用户进行调整。

esbuild 主打一个快速,但是不支持插件配置,也不支持热更新,他是 2019 年首次发布的,因此它相对较新。所以目前为止有些插件和 esbuild 并不兼容,这也就是 vite 的打包使用了 rollup 而没有用 esbuild 的原因,相对而言 rollup 有更活的插件 api 和基础建设。

一下内容来自 vite 官网

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(10)

可以跟着esbuild  官网进行学习,esbuild 不支持插件,也不支持热更新。

详细代码请参看项目的这个文件夹。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(11)

4.2.1 为啥会快

那么问题来了,问什么esbuild会这么快?

  1. 用 Go 编写:esbuild 是用 Go 编写的,Go 是一种编译型语言,具有出色的性能和并发能力。esbuild 利用了 Go 的特性,通过并行编译和高效的资源管理,实现了快速的构建速度。

  2. 高效的算法和数据结构:esbuild 使用了一些高效的算法和数据结构来加速构建过程。例如,它使用了一种称为并行增量算法的技术,可以有效地处理多个模块并行编译,从而提高了构建的效率。

  3. 零分析的工作方式:esbuild 不会像其他工具那样对整个项目进行完整的分析,而是仅仅对被导入的模块进行编译。这种零分析的工作方式大大减少了构建过程中的计算量,从而提高了构建速度。

  4. 基于原生代码生成器:esbuild 采用了一种基于原生代码生成器的方法,可以直接生成高效的原生代码,而无需通过中间表示或额外的转换步骤。这样可以减少构建过程中的不必要的计算和内存开销,从而提高了构建的速度。

4.3 vite

 Vite 是一种新型的前端构建工具,特别设计用于快速开发。Vite 支持使用原生 ES 模块作为开发环境,采用按需编译的方式,因此在开发过程中能够获得更快的冷启动速度。Vite 集成了 Vue.js,但也可以用于其他框架或库。

常见问题

vite 是我们常用的一个打包工具,有三个问题我们理解了,基本就涵盖了面试题中的问题,分别是

  1. vite 的原理
  2. vite 的热更新原理
  3. vite 的构建流程

可以点进去看一下详细内容,有一点需要补充一下,这些内容在 vite 的官网实际上都有详细的描述,所以说官网是个好东西,建议大家都去看一遍官网,常看常新。

优点

  • 利用 esm, 快速的冷启动
  • 即时的热更新
  • 动态导入,按需编译

缺点

  • 功能不如 webpack 强大

接下来还是实现一个简单的demo,我不使用脚手架,也不用 vue 等框架,就自己写一个。

4.3.1 新建 vite 文件夹

新建 vite 文件夹后,并运行下面命令,跳转到该文件夹下面

cd vite

4.3.2 初始化项目

在 vite 文件夹下面,运行下面的命令

npm init -y

4.3.3 安装 vite

在 vite 文件夹下面,运行下面的命令

npm i vite -D

4.3.4 新建 index.html / index.js

index.html 作为入口文件,并在 index.html 中 引入 index.js

代码如下




    
    
    Document


    

vite

// index.js
export const name = 'vite'

console.log('inner name', name)

4.3.5 配置 dev 命令

在 package.json 中配置

"scripts": {
    "dev": "vite"
  },

4.3.6 运行项目

npm run dev

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(12)

4.3.7 重点说明

在 vite 热更新的原理这篇文章,我们提到适用了 websocket 并且,在启动的时候会向客户端注入一个 js 文件。我们来看一下我们的项目中就可以看到 /@vite/client 文件。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(13)

可以自己在源代码中查看

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(14)

4.3.8 增加配置

新增 vite.config.js ,可以根据官网进行各种配置,比如配置启动的端口号。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(15)

4.3.9 热更新

上面的这篇文章中提到了,vite 的热更新是使用了 websocket 原理,我们可以正好测试一下,启动项目的 demo,然后修改 html 的内容,会发现有 有些网络请求,可以自己看一下。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(16)

这部分代码在下面这个文件夹中,可以参考。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(17)

好了, vite 还是相对简单的构建工具,我们还剩一个最重要的重头戏 webpack,加油坚持就是胜利。

4.4. webpack

Webpack 是一个模块打包工具,它能够将各种资源(JavaScript、CSS、图片等)打包成一个或多个静态文件,以优化加载性能。

常见问题

webpack 是一个强大的构建工具,主要涉及到的重点问题有

  1. 对 webpack 的理解,webpack 有哪些功能?
  2. 说一下 webpack 的构建流程
  3. webpack 的热更新原理
  4. webpack 的 tree-shaking 原理
  5. webpack 的 loader 和 plugin 的区别,分别的实现思路
  6. webpack 常见的 loader 和 plugin
  7. 如何提高 webpack 的构建速度
  8. webpack 中的 module、bundle、chunk 分别是指什么
  9. webpack 中 hash、contenthash、chunkhash 的区别是什么
  10. webpack 中常用的生命周期​​​​​​​

依次看完这 9 个问题,基本上就对 webpack 的理论知识有了一定的了解,现在我们还是跟着官网动手写一个 demo 吧。

4.4.1 新建 webpack 文件夹

新建 webpack 文件夹后,并运行下面命令,跳转到该文件夹下面

cd webpack

4.4.2 初始化项目

在 webpack 文件夹下面,运行下面的命令

npm init -y

4.4.3 安装 webpack 等

在 webpack 文件夹下面,运行下面的命令

npm i -D webpack webpack-cli  webpack-dev-server html-webpack-plugin

【webpack-cli】Command Line Interface 是 Webpack 的命令行工具,用于在命令行中运行和配置 Webpack。

【webpack-dev-server】是 webpack 的开发服务器,用于开发中的热更新,自动编译等功能。

【html-webpack-plugin】是 webpack 的 html 插件,可以将打包后的 js 等资源文件挂载到 html中,进行预览、开发。

4.4.4 依次新建如下文件

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(18)
 

都一些简单的代码,其中重要的配置是在 webpack.config.js 中,具体的可以在后面我的仓库中查看。

const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
    mode: 'development',
    entry: {
        // 配置多个入口文件,就会有多个 bundle 捆绑包,就要配置多个output
        main: './main.js',
        login: './login.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        // 打包后的文件名,因为是多入口,所以要按照入口文件名区分
        // 下面这个 name / chunkhash 都是是固定写法
        // 这里面就涉及到著名的面试题  hash, chunkhash, contenthash 有什么区别,入口文件一般用 chunkhash
        // 可以试下,不同的写法打包后有啥不同的效果
        filename: 'bundle.[name].[hash].js',
        // filename: 'bundle.[name].[chunkhash].js',
        // filename: 'bundle.[name].[contenthash].js'    
    },
    devServer: {
        port: 3001
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 打包后的文件名,这个文件名也可以用  hash, chunkhash, contenthash 
            // 但是如果用来哈希值,每次大包的名字不一样,在开发过程中的路由每次就会变不方便我们开发
            filename: 'main.html', 
            template: 'main.html', //自己写的html文件
        }),
        new HtmlWebpackPlugin({
            filename: 'login.html', //打包后的文件名
            template: 'login.html', //自己写的html文件
        }),
    ]
}

4.4.5 配置运行脚本

 需要在 package.json 中配置开发和打包的脚本

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(19)

4.4.5 运行项目

运行 npm run dev

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(20)

访问 http://localhost:3001/login.html

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(21)

我们在看一下 html 的内容,它把脚本加上了 defer,代表了脚本异步加载,加载之后等待 html 解析后才执行,注意 defer 和 async 的区别,请参考这篇文章。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(22)

4.4.5 hash / chunkhash / contenthash

光说不练假把式,我们还是实际是一下这三个单词的区别吧。

(1)hash

入口文件名,设置为【hash】,然后运行打包命名 npm  run pack,你会发现,所有文件共用一个哈希值。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(23)

此时我们只对其中的一个 js 文件 login.js 做出改动,然后重新打包,你会发现重新生成了两个 js 文件,没有改动的 main.js 也重新打包了

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(24)所以说 hash, 是所有文件公用一个哈希值,一个文件改动,所有文件都会被重新打包,所有的文件名都会发生改变。

(2)chunkhash

我们再来看一下 chunkhash,首先把 dist 文件夹里面的内容清空,然后打包。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(25)

改变 login.js 的内容,重新打包,发现只新打包了 login

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(26)

我们刚才是改动了 login.js ,现在我们改动 loginInfo.js ,login 引用了 loginInfo,【换言之,loginInfo.js 是 login.js 的依赖】再重新打包。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(27)

会发现也会重新打包,所以说,在入口文件的依赖发生改变时,也会重新打包,这是很好理解的,因为 webpack 会根据入口文件依次打包它的依赖文件整合到一个文件中,所以一个依赖发生变化,生成的资源文件肯定发生变化。

chunkhash 就很适合用来打包入口文件,这样每个入口文件以及依赖发生变化,只会重新打包发生变化的文件,而不会影响其他的入口文件。

(3)contenthash

我们修改一下项目,增加一个css 的插件,依次安装下面的插件

npm i css-loader mini-css-extract-plugin -D

【css-loader】使得能够在 js 中 import css 文件加载样式

【mini-css-extract-plugin】可以把 js 文件单独打包成一个文件,如果不适用这个插件,就会把 css的内容打包到引用它的 js 文件中。

新增 index.css ,并在 login.js 中引用

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(28)

此时 webpack.config.js 的配置如下

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(29)

现在我们配置的是 chunkhash,打包之后内容如下

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(30)

修改 login.js ,注意修改的是js文件,重新打包,会发现 css 文件也重新打包,但是其实css 的文件没有做任何改动。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(31)

所以我们这个时候可以使用 contenthash,再来重复上面的操作。

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(32)

小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏插图(33)

所以说 contenthash 是只有在内容发生变化的时候,哈希值才会变化,一般用于打包 css 文件,这对于缓存很有用。

三个哈希值的对比,请参考这篇文章。

五、总结

本篇文章所有的代码都在这个仓库中,内容不是很多,所以没有特别详细的按照步骤提交,不过每个工具的代码都是独立的,有任何问题欢迎在评论区指正。

至此,基本上前端涉及到的流行的构建工具都已经自己写了一个 demo,其中 vite 和 webpack 的尤为重要,webpack 是高频面试题,所以还是需要好好看一下官网,理解一下原理。

欢迎关注我的专栏《前端工程化系统教程》和《面试题一网打尽》内容持续更新中。

本站无任何商业行为
个人在线分享 » 小白必看,总结前端所有主流的构建工具,webpack / vite / roollup / esbuild,包含源码,建议关注+收藏
E-->