王柳 发表于 2024-12-16 08:10:05

小白必看,总结前端全部主流的构建工具,webpack / vite / roollup / esbui

前言

本篇文章旨在总结前端常见的构建工具,构建工具是前端工程化中的重要的构成部分。
在实际项目中,我们初始化项目,一样寻常是利用脚手架命令一键天生的,比如说利用 create-vue 初始化 vue 项目的时候,就会默认利用 vite 进行打包,同理利用 vue-cli 的时候就是默认利用webpack进行打包(现在vue已经不推荐利用这种方式了)
pnpm create vue@latest https://i-blog.csdnimg.cn/blog_migrate/7ceca6ca791ae71222f6a0d92dc16424.png
利用脚手架初始化项目简单又方便,很多东西都是现成的,但是这就导致有的时候新手小白不会去认真看打包工具的官网,误以为诸如 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】
https://i-blog.csdnimg.cn/blog_migrate/54995a31ac41fa8d6090f5ef4330f109.png
我们可以跟着 grunt 的官网来学一下到底怎么用,恕我直言,我也没用过这个工具,但是跟着官网一步一步来,是可以很轻易打包一个 js 文件的。
详细代码请参看项目的这个文件夹
https://i-blog.csdnimg.cn/blog_migrate/42f9ae5a9ee36b58ef3a91759b2125c1.png​
重点是 Gruntfile.js 这个文件,在这个文件中【定义使命】—> 【注册使命】可以利用各种插件,grunt 有很多可以利用的插件,总之我们必要明白 grunt 是基于使命的构建工具。
2.2 gulp

 Gulp 也是一个基于使命的构建工具,通过定义一系列使命,可以实现对前端项目的自动化构建,包罗文件的合并、压缩、编译等。Gulp 原生就可以支持使命的串行、并行执行。
   Gulp 则是另一个 JavaScript 使命运行器,它更加基于代码,利用流/管道(stream)来定义使命。开发者通过编写 JavaScript 代码来设置使命,这使得使命的定义更加灵活、简洁。Gulp 的流式处置惩罚方式通常被以为更加直观和易于明白。
    https://i-blog.csdnimg.cn/blog_migrate/65739075f1537695af3577212a870cca.png
g ao p​
同样的我们跟着 gulp 的官网一步一步来实现一个简单的 demo。
详细代码请参看项目的这个文件夹
https://i-blog.csdnimg.cn/blog_migrate/b03917fcf4a42090d9bc31a75f3b9e44.png​
2.3 grunt 和 gulp 的区别

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

[*] 设置方式:

[*]Grunt 利用基于设置的方式来定义使命,通常在一个名为 Gruntfile.js 的文件中指定使命和使命的设置。这种方式必要开发者编写较多的设置代码。
[*]Gulp 利用基于代码的方式来定义使命,开发者可以编写 JavaScript 代码来设置使命,利用管道(streams)来处置惩罚文件。这种方式相对于 Grunt 更加直观和灵活。

[*] API 和插件:

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

[*] 性能:

[*]Gulp 的流式处置惩罚方式使得使命可以并行执行,因此在处置惩罚大量文件时大概会比 Grunt 更快。
[*]Grunt 的使命通常是串行执行的,固然可以通过一些插件实现并行执行,但默认环境下较为常见的是串行执行使命。

[*] 易用性和可读性:

[*]由于 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 的设置文件。
详细代码请参看项目的这个文件夹
https://i-blog.csdnimg.cn/blog_migrate/877dd9cc3fb261a9f988ac779c6713a2.png
   我个人以为,如果你本身写一个学习的项目,不考虑性能,用这个打包是绝佳的首选,简单好上手,零设置真是强推。
但是如果在实际的项目中,我们就要考虑性能等各种方面,parcel 没有webpack 的社区活跃,功能强大。
parcel 2的官网里面表现也支持插件等,功能比1 强大很多,有爱好可以试着学习一下(我没有爱好~~)
https://i-blog.csdnimg.cn/blog_migrate/2a037357c66a69d8dc87bdb5c2123034.png

3.2 browserify

 Browserify 答应在前端利用类似于 Node.js 的 require 语法,将模块化的 JavaScript 文件打包成一个文件,以便在欣赏器中利用,它打包后的文件可以直接在html 中引用。
   
[*] 模块化开发:Browserify 答应开发者利用模块化的方式构造 JavaScript 代码,使得代码更易于维护、重用和测试。通过 require() 来引入模块,可以将代码分割成多个文件,每个文件负责一个特定的功能,有助于降低代码耦合度。
[*] 依赖管理:Browserify 自动处置惩罚模块之间的依赖关系,可以将各个模块打包到一个文件中,避免了手动管理依赖关系的繁琐工作。这简化了开发流程,进步了开发服从。
[*] 前端与后端代码共享:由于 Browserify 可以利用类似于 Node.js 的模块体系,在一定程度上实现了前端和后端代码的共享,使得开发者可以更轻易地在前端和后端之间共享代码和逻辑,进步了代码复用性和一致性。
[*] 利用 npm 生态体系:Browserify 可以直接利用 npm 上的模块,这意味着您可以利用 npm 生态体系中丰富的第三方模块和工具来加快开发,无需额外的学习成本。
[*] 支持预处置惩罚器:除了 JavaScript 模块外,Browserify 还支持预处置惩罚器,如通过适当的插件,可以利用 CoffeeScript、TypeScript、Less 等语言,并将其编译成欣赏器可执行的 JavaScript 代码。
如果你用过 webpack 等主流的构建工具,你会发现 browserify 有的功能,webpack 也有,因为 browserify 是先提出来的,所以有了webpack 之后就不咋用了。
   看出来了,它的焦点优势就是前端利用类似于 Node.js 的 require 语法
https://i-blog.csdnimg.cn/blog_migrate/ce3907a75b8f65c4934110887956bcf0.png
 同样的我们跟着 browserify 的官网实现一个简单的demo,看看怎么回事。
详细代码请参看项目的这个文件夹,在这个demo中也是没有设置文件,只是单纯的利用 browserify 打包了一个 js 文件。
https://i-blog.csdnimg.cn/blog_migrate/ca50dc21fd662e1bfdc600e2a1fea70a.png
四、重要的基于模块的构建工具

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

[*]都是基于模块的构建工具:都用于将多个 JavaScript 模块打包成一个或多个欣赏器可执行的文件。它们可以处置惩罚不同范例的模块(例如 CommonJS、ES6 模块等)并将它们合并为一个输出文件
[*]优化和压缩,都支持 tree-shaking:提供了代码优化和压缩的功能,以减少输出文件的大小并进步页面加载速度。它们可以去除未利用的代码(Tree-shaking)、进行代码压缩、合并文件等操作。
[*]插件体系: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 支持设置文件,支持插件,但是不支持热更新。
详细代码请参看项目的这个文件夹。
https://i-blog.csdnimg.cn/blog_migrate/6cbec65a4f99390f0565ab785ab5be1f.png
   如果你在本身学习一个新的技能,也可以是试着利用 rollup 进行打包。不外 rollup 不支持热更新,不如之前说的 parcel 方便。
4.2 esbuild

esbuild 是一个非常快速的 JavaScript 和 TypeScript 构建工具。它以极快的速度执行构建使命,并支持 Tree-shaking,即消除未利用的代码。esbuild 被计划成一个零设置的工具,但也提供了一些设置选项供用户进行调解。
   esbuild 主打一个快速,但是不支持插件设置,也不支持热更新,他是 2019 年首次发布的,因此它相对较新。所以目前为止有些插件和 esbuild 并不兼容,这也就是 vite 的打包利用了 rollup 而没有用 esbuild 的原因,相对而言 rollup 有更活的插件 api 和底子建立。

一下内容来自 vite 官网
https://i-blog.csdnimg.cn/blog_migrate/3cdcb634343a870f54919e696b190710.png
可以跟着esbuild  官网进行学习,esbuild 不支持插件,也不支持热更新。
详细代码请参看项目的这个文件夹。
https://i-blog.csdnimg.cn/blog_migrate/1149f16aac6b1046e9c9901dbe6fdd15.png
4.2.1 为啥会快

那么问题来了,问什么esbuild会这么快?
   
[*] 用 Go 编写:esbuild 是用 Go 编写的,Go 是一种编译型语言,具有精彩的性能和并发本领。esbuild 利用了 Go 的特性,通过并行编译和高效的资源管理,实现了快速的构建速度。
[*] 高效的算法和数据结构:esbuild 利用了一些高效的算法和数据结构来加快构建过程。例如,它利用了一种称为并行增量算法的技能,可以有效地处置惩罚多个模块并行编译,从而进步了构建的服从。
[*] 零分析的工作方式:esbuild 不会像其他工具那样对整个项目进行完备的分析,而是仅仅对被导入的模块进行编译。这种零分析的工作方式大大减少了构建过程中的计算量,从而进步了构建速度。
[*] 基于原生代码天生器:esbuild 接纳了一种基于原生代码天生器的方法,可以直接天生高效的原生代码,而无需通过中间表示或额外的转换步骤。如许可以减少构建过程中的不必要的计算和内存开销,从而进步了构建的速度。
4.3 vite

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

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

[*]vite 的原理
[*]vite 的热更新原理
[*]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
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>vite</h1>
    <!-- 以模块的形式导入 index.js -->
    <script type="module" src="./index.js"></script>
    <script>
      // 这里面可以得到name
      console.log('outer name', name)
    </script>
</body>
</html> // 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 https://i-blog.csdnimg.cn/blog_migrate/fafc39ce42b910b0ef2256a2d94d0806.png
4.3.7 重点说明

在 vite 热更新的原理这篇文章,我们提到实用了 websocket 而且,在启动的时候会向客户端注入一个 js 文件。我们来看一下我们的项目中就可以看到 /@vite/client 文件。
https://i-blog.csdnimg.cn/blog_migrate/e725730ece3dff64a92e23fe506f2af7.png
可以本身在源代码中检察
https://i-blog.csdnimg.cn/blog_migrate/90818e131900813a0abc10659f6bce9b.png
4.3.8 增长设置

新增 vite.config.js ,可以根据官网进行各种设置,比如设置启动的端标语。
https://i-blog.csdnimg.cn/blog_migrate/5ed2cc01d8e2571d9c4d2d929f7ef269.png
4.3.9 热更新

上面的这篇文章中提到了,vite 的热更新是利用了 websocket 原理,我们可以正好测试一下,启动项目的 demo,然后修改 html 的内容,会发现有 有些网络哀求,可以本身看一下。
https://i-blog.csdnimg.cn/blog_migrate/edf64936f4cddd2d635a14df0138f64b.png
这部分代码在下面这个文件夹中,可以参考。
https://i-blog.csdnimg.cn/blog_migrate/241d20cc62bb191dcd6c04afbd6f4421.png
好了, vite 照旧相对简单的构建工具,我们还剩一个最重要的重头戏 webpack,加油坚持就是胜利。
4.4. webpack

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

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

[*]对 webpack 的明白,webpack 有哪些功能?
[*]说一下 webpack 的构建流程
[*]webpack 的热更新原理
[*]webpack 的 tree-shaking 原理
[*]webpack 的 loader 和 plugin 的区别,分别的实现思路
[*]webpack 常见的 loader 和 plugin
[*]如何进步 webpack 的构建速度
[*]webpack 中的 module、bundle、chunk 分别是指什么
[*]webpack 中 hash、contenthash、chunkhash 的区别是什么
[*]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-cliwebpack-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 依次新建如下文件

https://i-blog.csdnimg.cn/blog_migrate/e1265807a20cd4e42625b5cf4fb04d5a.png
 
都一些简单的代码,其中重要的设置是在 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...js',
      // filename: 'bundle...js',
      // filename: 'bundle...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 中设置开发和打包的脚本
https://i-blog.csdnimg.cn/blog_migrate/4a65b4f92c83891137483505734bb162.png
4.4.5 运行项目

运行 npm run dev
https://i-blog.csdnimg.cn/blog_migrate/9f9bf39f61995c7891044c6abe38293b.png
访问 http://localhost:3001/login.html
https://i-blog.csdnimg.cn/blog_migrate/358fd43bbfa527a53dc6b2d3d393b541.png
我们在看一下 html 的内容,它把脚本加上了 defer,代表了脚本异步加载,加载之后期待 html 解析后才执行,注意 defer 和 async 的区别,请参考这篇文章。
https://i-blog.csdnimg.cn/blog_migrate/dd10aad2d2540c08ba440119c203d0e8.png
4.4.5 hash / chunkhash / contenthash

光说不练假把式,我们照旧实际是一下这三个单词的区别吧。
(1)hash

入口文件名,设置为【hash】,然后运行打包命名 npm  run pack,你会发现,全部文件共用一个哈希值。
https://i-blog.csdnimg.cn/blog_migrate/a9b9076d4bc31f640a15819610397b53.png
此时我们只对其中的一个 js 文件 login.js 做出改动,然后重新打包,你会发现重新天生了两个 js 文件,没有改动的 main.js 也重新打包了
https://i-blog.csdnimg.cn/blog_migrate/eb38959907b611b0fc653fa3989abcbe.png所以说 hash, 是全部文件公用一个哈希值,一个文件改动,全部文件都会被重新打包,全部的文件名都会发生改变。
(2)chunkhash

我们再来看一下 chunkhash,起首把 dist 文件夹里面的内容清空,然后打包。
https://i-blog.csdnimg.cn/blog_migrate/a397c5cfb95c21f8045078b32b62e429.png
改变 login.js 的内容,重新打包,发现只新打包了 login
https://i-blog.csdnimg.cn/blog_migrate/6d707d5b01cc64ec7ed6cad4f9b852c5.png
我们刚才是改动了 login.js ,现在我们改动 loginInfo.js ,login 引用了 loginInfo,【换言之,loginInfo.js 是 login.js 的依赖】再重新打包。
https://i-blog.csdnimg.cn/blog_migrate/de059dfe380483482563e1c234d4ce85.png
会发现也会重新打包,所以说,在入口文件的依赖发生改变时,也会重新打包,这是很好明白的,因为 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 中引用
https://i-blog.csdnimg.cn/blog_migrate/0da85a62e2a37b82f7918cb0d5a16464.png
此时 webpack.config.js 的设置如下
https://i-blog.csdnimg.cn/blog_migrate/0fbb3a4347cb66d428d741f168a62cc3.png
现在我们设置的是 chunkhash,打包之后内容如下
https://i-blog.csdnimg.cn/blog_migrate/2b63f7b55fe785c1ab4ed1609f5be714.png
修改 login.js ,注意修改的是js文件,重新打包,会发现 css 文件也重新打包,但是其实css 的文件没有做任何改动。
https://i-blog.csdnimg.cn/blog_migrate/ba0336ecef6ca44ec5f420abd9732614.png
所以我们这个时候可以利用 contenthash,再来重复上面的操作。
https://i-blog.csdnimg.cn/blog_migrate/df318d372e008e7defbf3e390cc63629.png
https://i-blog.csdnimg.cn/blog_migrate/4b7b2b726469f5aeae6ef29b952ac930.png

所以说 contenthash 是只有在内容发生变化的时候,哈希值才会变化,一样寻常用于打包 css 文件,这对于缓存很有用。
三个哈希值的对比,请参考这篇文章。
五、总结

本篇文章全部的代码都在这个仓库中,内容不是很多,所以没有特殊详细的按照步骤提交,不外每个工具的代码都是独立的,有任何问题欢迎在批评区指正。
至此,基本上前端涉及到的流行的构建工具都已经本身写了一个 demo,其中 vite 和 webpack 的尤为重要,webpack 是高频面试题,所以照旧必要好好看一下官网,明白一下原理。
欢迎关注我的专栏《前端工程化体系教程》和《面试题一扫而空》内容连续更新中。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 小白必看,总结前端全部主流的构建工具,webpack / vite / roollup / esbui