前端构建(打包)工具发展史

大多同学的前端学习路线:三件套+框架+慢慢延伸到其他,在这个过程中,有一个词出现的频率很高:webpack 。

作为一个很出名的前端构建工具我们在网上随便一搜,就会有各种教程:loader plugin entry吧啦吧啦。

但是为什么会有它,为什么我们离不开它呢? 如何理解“构建工具”四个字?它和“打包工具”又有什么关系呢?用法和api其实很好找,但是这几个问题的答案找起来却有点难度:相关的解释都零零散散,于是决定做这么一个分享,希望能以不一样的角度带给大家新的启发。 以上就是写这篇文章的初衷

目录

何为前端构建(打包)工具

构建工具发展史

 1.石器时代

2.蒸汽时代

3.近现代

4.现代

回顾


何为前端构建(打包)工具

现代的前端构建主要包括两部分:transformbundle

1.transform(代码转换): 的作用就是将 TypeScript/JavaScript/JSX 等高级语法 (es6语法浏览器直接运行可能会不兼容)转化适合浏览器/Node.js 运行的相关标准的 javascript 的过程。

2.bundle(代码打包):从开发者设置的入口出发,分析模块依赖,加载并将各类资源最终打包     成1个或多个文件。

所以,“打包工具”是“构建工具”的一部分。

构建工具发展史

接下来会按照前端发展为时间线来进行讲解,以前端大事件为节点进行分割,来分析讲解当时的前端困境以及对应的构建情况。

 1.石器时代

标志性事件:1990年浏览器的诞生。

在这段时间,除了浏览器,还诞生了很多东西:WWW(World Wide Web)的诞生、JavaScript的诞生、W3C、PHP......

此时的前端:那个时候页面基本是纯静态的或者服务端输出 没有专业的前端,页面全是由后端开发 在很长的一段前端历史里,是不存在打包/构建这个说法的。

2.蒸汽时代

2.1标志性事件:2005年AJAX被拾起。

ps:XMLHttpRequest是2000年就有了,但是由于推广以及存在的问题(需要浏览器提供支持,存在跨域问题),导致它刚开始并没有被人们注意,到 2005 年 Ajax 和 Web 2.0 变得流行才被人注意。

为什么说AJAX对前端具有非凡意义呢?

想象一下,之前前端页面展示在浏览器中 是后端一整个页面发过来,有数据更改,后端改了之后,把一整个新的页面再发过来(也就指常说的:页面整个刷新)。

有了ajax之后,发过来页面之后,如果有更新,只需要网络交互有更改的地方

也就是:整个页面刷新---->部分刷新(将页面/呈现和数据分离!交互的粒度变小了)    

意味着可以把以前一些服务器负担的工作转嫁到客户端

js能做的事愈来愈多,前端开发者开始往页面里插入各种库和插件,我们的 js 文件程指数倍的开始增加。

2.2此时遇到的问题

1.运行环境限制:js作为一门脚本语言,只能在浏览器运行(没有node的时候),只能通过<script>标签 插进html去运行去引那些js文件,还得注意引用顺序和插入的位置,一方面难以维护, 一方面增加了网页加载时的请求数量。

2.代码分割管理的问题:引用一些脚本来存放每个功能;此解决方案很难扩展,因为加载太多脚本会 导致网络瓶颈。

3.可维护性:使用一个包含所有项目代码的大型 .js 文件,但是这会导致作用域、文件大小、 js文件间的文件依赖难以维护,可读性差等问题。

举个例子:比如说如果要用bootstrap,只需要在 script 标签中引入对应库的 cdn 链接即可, 然而由于 bootstrap 依赖于 jquery,我们必须把引入 jquery 的标签写在 bootstrap 的《前面》,不然就会导致报错。

如果一个网站功能很多,我要按照功能划分写15个js文件, 那我就要插入15个<script src=""> 去引那些js文件,还tm得注意引用顺序和插入的位置,一方面难以维护, 一方面增加了网页加载时的请求数量(15个不算多,如果是200个js文件的话,维护起来会多令人崩溃。。。)

2.3当时的解决办法:JS压缩。

压缩主要做了局部变量命名简化、空格/换行/注释消除、自动优化可简化的语法等工作

一般是通过在window上用bat脚本或者mac/linux上的shell脚本来决定合并哪些文件、用什么工具压缩、怎么压缩。

JSMin、YUI Compressor、Closure Compiler、UglifyJS 等js 文件压缩合并工具在当时陆陆续续诞生。

2.4存在的问题

但是这种解决办法依旧存在问题:

举个例子,当a文件和b文件都引用了c文件的方法时,如果把c文件分别和ab合并, 这样就只有两个文件了这就是最开始的合并方式。 工程化的项目里相互依赖关系变得很是复杂 合并的文件里可能会有不少重复/无用代码。

3.近现代

3.1标志性事件:Node.js的诞生(2009)和随之诞生的各种JS规范(commonJS AMD CMD ECMAscript等)。

之前我们说什么?js只能在浏览器里面执行 node可以在浏览器环境之外的计算机和服务器中使用。 commonjs的require机制为js引入了模块化。

3.2此时遇到的问题

1.浏览器兼容问题:尽管现如今主流浏览器的最新版本都支持这一特性, 但是在几年前的我们还无法忽略用户存在使用老版本浏览器的 case, 所以我们还需要考虑兼容问题。

2.网络性能问题:模块化的方式划分出来的模块文件过多, 而前端应用又运行在浏览器中,每一个文件都需要单独从服务器请求回来。 零散的模块文件必然会导致浏览器的频繁发送网络请求,由于上文所述的 Http1.x 的能力局限性, 进而会影响应用使用体验。

3.模块化需求:随着应用日益复杂,在前端应用开发过程中不仅仅只有 JavaScript 代码需要模块化,HTML 和 CSS 这些资源文件也会面临需要被模块化的问题。(sass ejs)

4.打包时候的额外工作: ES6 -> ES5 ,TS -> JS, less / scss -> css等

3.3当时的解决办法:颇具代表性的构建工具webpack来了!(2014)

(ps:同时期还有其他也很优秀的构建工具,如rollup等,这里挑的是比较有代表性的webpack来讲解)

我们上文提到,构建工具包含transform 和 bundle两部分,webpack主要负责打包(bundle),同时它那些loader/plugin让他能够去转化代码(transform)。

所以如果我们回看此时的困境,webpack其实差不多都能解决的7788了(webpack有大量的plugin和loader兼容性问题,代码转换问题 以及webpack还引入了异步地加载 chunk 和预取等等来进行性能优化,来弥补网络性能问题等等)

3.4存在的问题:主要是dev环境(即开发环境)下的问题

我们项目中的所有代码最终都被打包到了一起,如果我们应用非常复杂, 模块非常多的话,我们的打包结果就会特别的大,加载时间就会很长。 项目的启动速度也会越来越慢(因为每次都要重新打包)。

为了解决这个问题,我们可以分包,HMR(模块热替换Hot Module Replacement),以及还有其他优化方法,就不多赘述。

4.现代

我们想要的:让我们在生产环境下,更快的构建出对应的产出文件

上文我们提到了dev环境下构建工具存在的缺陷,那么为了解决这个缺陷,一个概念被提出:bundleless

bundleless:顾名思义,就是不打包。

颇具代表性的就是vite

这里的不打包,侧重的是dev环境下的不打包,生产环境该打还得打(vite打包使用的是RollUp)。

基本原理:依赖浏览器原生支持esm 去解析模块。

为什么快:vite可以不用打包,只需要更新修改过的文件即可

PS:在查资料的时候,觉得vite和和webpack的一个plugin很像:webpack-dev-server

都是用在开发环境的,提高开发效率的(把代码读取到内存中)。

查了一下:大致过程和webpack-dev-server的差不多,但是vite可以不用打包,只需要更新修改过的文件即可

而和webpack-dev-server最主要区别则是:每次更新都会重新打包编译,所以没有vite快。

回顾

总结一下,不外乎这几种原因催,生了技术一次又一次的革新和发展:

需求,语言越来越多样化

对性能要求越来越大

项目(代码量)复杂度越来越大

其他技术(如硬件等)的发展

。。。。。

最后,希望这次“另辟蹊径”的分享能带给大家不一样的启发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/53665.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【福建事业单位-推理判断】04定义判断、事件排序

一、定义判断 1.1、关键词——主客体 千万不要过度脑补 需要注意限定语&#xff0c;被限定的主体和客体。 找到主谓宾&#xff0c;和限定与 社会救助每次出题&#xff0c;都会有一个不涉及生存保障的易错选项。 1.2句式引导词 通过引导词&#xff0c;找到定义中的关键内容…

同为科技(TOWE)带热插拔功能机柜PDU插座的应用

所谓热插拔&#xff08;hot-plugging或Hot Swap&#xff09;&#xff0c;即带电插拔&#xff0c;指的是在不关闭系统电源的情况下&#xff0c;将模块、板卡插入或拔出系统而不影响系统的正常工作&#xff0c;从而提高了系统的可靠性、快速维修性、冗余性和对灾难的及时恢复能力…

docker compose一键部署lnmt环境

创建docker compose 目录 [rootlocalhost ~]# mkdir -p /compose_lnmt 编写nginx的dockerfile文件 创建目录 [rootlocalhost compose_lnmt]# mkdir -p nginx 编写nginx配置文件 [rootlocalhost nginx]# vim nginx.conf user root; #运行身份#nginx自动设置进程…

【深度学习_TensorFlow】梯度下降

写在前面 一直不太理解梯度下降算法是什么意思&#xff0c;今天我们就解开它神秘的面纱 写在中间 线性回归方程 如果要求出一条直线&#xff0c;我们只需知道直线上的两个不重合的点&#xff0c;就可以通过解方程组来求出直线 但是&#xff0c;如果我们选取的这两个点不在直…

一百四十三、Linux——Linux的CentOS 7系统语言由中文改成英文

一、目的 之前安装CentOS 7系统的时候把语言设置成中文&#xff0c;结果Linux文件夹命名出现中文乱码的问题&#xff0c;于是决定把Linux系统语言由中文改成英文 二、实施步骤 &#xff08;一&#xff09;到etc目录下&#xff0c;找到配置文件locale.conf # cd /etc/ # ls…

38.利用matlab解 有约束无约束的参数估计对比(matlab程序)

1.简述 1.离散型随机变量的极大似然估计法: (1) 似然函数 若X为离散型, 似然函数为 (2) 求似然函数L(θ)的最大值点 θ, 则θ就是未知参数的极大似然估计值. 2.连续型随机变量的极大似然估计法: (1) 似然函数 若 X 为连续型, 似然函数为 (2) 求似然函数L(θ)的最大值点θ, 则…

基于ASP.NET MVC开发的、开源的个人博客系统

推荐一个功能丰富、易于使用和扩展的开源博客&#xff0c;可以轻松地创建和管理自己的博客。 项目简介 基于.Net Framework 4.5开发的、开源博客系统&#xff0c;具有丰富的功能&#xff0c;包括文章发布、分类、标签、评论、订阅、统计等功能&#xff0c;同时也可以根据需要…

vue2商城项目-01-总结

1.配置相关 1.1eslint关闭 说明&#xff1a;根目录创建vue.config.js module.exports {// 关闭eslintlintOnSave: false,};1.2src配置别名 说明&#xff1a;根目录创建jsconfig.json文件 {"compilerOptions": {"baseUrl": "./","path…

[Docker实现测试部署CI/CD----相关服务器的安装配置(2)]

目录 6、Jenkins安装配置安装jdk安装maven拉取镜像启动jenkins修改数据卷权限浏览器访问安装插件配置jenkins移动JDK和Maven配置JDK和Maven 6、Jenkins安装配置 Jenkins 是一个开源软件项目&#xff0c;是基于 Java 开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&…

java中io流、属性集Properties、缓冲流、转换流、序列化和反序列化、打印流、网络编程(TCP通信程序、文件复制案例、文件上传案例、B/S服务案例)

IO流&#xff1a; io流中i表示input输入&#xff0c;o表示output输出&#xff0c;流表示数据&#xff08;字符&#xff0c;字节&#xff0c;1个字符2个字节8个位&#xff09;&#xff1b;这里的输入输出是以内存为基础&#xff0c;将数据从内存中输出到硬盘的过程称为输出&…

Docker实战-操作Docker容器实战(一)

导语   在之前的分享中&#xff0c;我们介绍了关于如何去操作Docker镜像&#xff0c;下面我们来看看如何去操作容器。 简单来讲&#xff0c;容器是镜像运行的一个实例&#xff0c;与镜像不同的是镜像只能作为一个静态文件进行读取&#xff0c;而容器是可以在运行时进行写入操…

SpringBoot中Redis报错:NOAUTH Authentication required

1、问题 org.springframework.dao.InvalidDataAccessApiUsageException: NOAUTH Authentication required.; nested exception is redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required. … 2、解决 如果提供了密码还没解决&#xff0c;那可能是…