前端构建(打包)工具发展史
大多同学的前端学习路线:三件套+框架+慢慢延伸到其他,在这个过程中,有一个词出现的频率很高:webpack 。
作为一个很出名的前端构建工具我们在网上随便一搜,就会有各种教程:loader plugin entry吧啦吧啦。
但是为什么会有它,为什么我们离不开它呢? 如何理解“构建工具”四个字?它和“打包工具”又有什么关系呢?用法和api其实很好找,但是这几个问题的答案找起来却有点难度:相关的解释都零零散散,于是决定做这么一个分享,希望能以不一样的角度带给大家新的启发。 以上就是写这篇文章的初衷
目录
何为前端构建(打包)工具
构建工具发展史
1.石器时代
2.蒸汽时代
3.近现代
4.现代
回顾
何为前端构建(打包)工具
现代的前端构建主要包括两部分:transform 和 bundle
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快。
回顾
总结一下,不外乎这几种原因催,生了技术一次又一次的革新和发展:
需求,语言越来越多样化
对性能要求越来越大
项目(代码量)复杂度越来越大
其他技术(如硬件等)的发展
。。。。。
最后,希望这次“另辟蹊径”的分享能带给大家不一样的启发。
相关文章:
前端构建(打包)工具发展史
大多同学的前端学习路线:三件套框架慢慢延伸到其他,在这个过程中,有一个词出现的频率很高:webpack 。 作为一个很出名的前端构建工具我们在网上随便一搜,就会有各种教程:loader plugin entry吧啦吧啦。 但…...
【数据可视化】(一)数据可视化概述
目录 0.本章节概述 一、数据可视化 1、什么是数据可视化? 2、数据可视化的好处 3、数据可视化的用途 二、数据探索 1、数据相关工具的使用情景: 2、探索性查询 三、数据挑战 1、什么是数据挑战?...
GoogleLeNet Inception V2 V3
文章目录 卷积核分解第一步分解,对称分解第二步分解,非对称分解在Inception中的改造一般模型的参数节省量可能导致的问题 针对两个辅助分类起的改造特征图尺寸缩减Model Regularization via Label Smoothing——LSR问题描述,也就是LSR解决什么…...
【css】背景图片附着
属性:background-attachment 属性指定背景图像是应该滚动还是固定的(不会随页面的其余部分一起滚动)。 background-attachment: fixed:为固定; background-attachment: scroll为滚动 代码: <!DOCTYPE h…...
解决运行flutter doctor --android-licenses时报错
问题描述: 配置flutter环境时,会使用flutter doctor命令来检查运行flutter的相关依赖是否配好。能看到还差 Android license status unknown.未解决。 C:\Users\ipkiss.wu>flutter doctor Flutter assets will be downloaded from https://storage.…...
在使用Python爬虫时遇到503 Service Unavailable错误解决办法汇总
在进行Python爬虫的过程中,有时会遇到503 Service Unavailable错误,这意味着所请求的服务不可用,无法获取所需的数据。为了解决这个常见的问题,本文将提供一些解决办法,希望能提供实战价值,让爬虫任务顺利完…...
小研究 - 主动式微服务细粒度弹性缩放算法研究(一)
微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放,忽略了能够充分利用单台服务器资源的细粒度垂直缩放,从而导致资源浪费。为此,本文设计了主动式微服务细粒度弹性缩放算法…...
【LeetCode】215.数组中的第K个最大元素
题目 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,6,4…...
MySQL学习记录:第七章 存储过程和函数
文章目录 第七章 存储过程和函数一、存储过程1、 创建语法*2、调用语法(1)空参列表(2)创建带in参数模式的存储过程,需终端运行(3)创建带out参数模式的存储过程,需终端运行(4)创建带inout参数模式的存储过程,需终端运行3、删除存储过程4、查看存储过程的信息二、函数…...
Docker中gitlab以及gitlab-runner的安装与使用
1、本文主要讲述如何使用Docker安装gitlab以及gitlab-runner,并且会讲述gitlab-runner如何使用 2、gitlab部分不需要修改过多的配置即可使用,本文未讲述https配置,如有需求,可自行百度 3、Docker如何安装可以自行百度 一、Docker安…...
一起学SF框架系列5.12-spring-beans-数据绑定dataBinding
数据绑定有助于将用户输入动态绑定到应用程序的域模型(或用于处理用户输入的任何对象),主要用于web层,但实际可用于任何层。Spring提供了DataBinder来做到这一点,并提供了Validator进行数据验证,两者组成了…...
火热报名中 | 赛宁独家技术支持第七届“蓝帽杯”网络安全技能大赛
由公安部网络安全保卫局、教育部教育管理信息中心、中国教育协会指导,中国人民公安大学主办,奇安信科技集团股份有限公司协办,南京赛宁信息技术有限公司提供技术支持的2023第七届“蓝帽杯”全国大学生网络安全技能大赛于近日正式开启报名。 …...
无涯教程-jQuery - Ajax Tutorial函数
AJAX是用于创建交互式Web应用程序的Web开发技术。如果您了解JavaScript,HTML,CSS和XML,则只需花费一个小时即可开始使用AJAX。 为什么要学习Ajax? AJAX代表 A 同步 Ja vaScript和 X ML。 AJAX是一项新技术,可借助XML,HTML,CSS和Java Script创建更好,更快,更具交互性的Web应用…...
Android日志
Android中的日志工具类是Log(android.util.Log),这个类中提供了如下5个方法来供我们打印日志。 Log.v()。用于打印那些最为琐碎的、意义最小的日志信息。对应级别verbose,是Android日志里面级别最低的一种。 Log.d()。用于打印一…...
【Golang 接口自动化08】使用标准库httptest完成HTTP请求的Mock测试
目录 前言 http包的HandleFunc函数 http.Request/http.ResponseWriter httptest 定义被测接口 测试代码 测试执行 总结 资料获取方法 前言 Mock是一个做自动化测试永远绕不过去的话题。本文主要介绍使用标准库net/http/httptest完成HTTP请求的Mock的测试方法。 可能有…...
SpringBoot自定义注解 + AOP+分布式Redis 防止重复提交
第一步 引入依赖pom.xml: <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.3</version> <!-- 使用最新版本 --></dependency><dependency><groupId&g…...
3.yum安装分布式LNMP--剧本
文章目录 修改hosts创建剧本文件 修改hosts vim /etc/ansible/hosts[webservers] 192.168.242.67[dbservers] 192.168.242.68[phpservers] 192.168.242.69创建剧本文件 vim lnmp.yaml- name: nginx playhosts: webserversremote_user: rootvars:- http_port: 192.168.242.67:…...
论文笔记:Fine-Grained Urban Flow Prediction
2021 WWW 1 intro 细粒度城市流量预测 两个挑战 细粒度数据中观察到的网格间的转移动态使得预测变得更加复杂 需要在全局范围内捕获网格单元之间的空间依赖性单独学习外部因素(例如天气、POI、路段信息等)对大量网格单元的影响非常具有挑战性——>论…...
系统集成|第八章(笔记)
目录 第八章 进度管理8.1 主要过程8.1.1 规划进度管理8.1.2 定义活动8.1.3 排列活动顺序8.1.4 估算活动资源8.1.5 估算活动持续时间8.1.6 制定进度计划8.1.7 控制进度 8.2 注意与问题 上篇:第七章、范围管理 第八章 进度管理 8.1 主要过程 包括: 规划进…...
【分布式】分布式唯一 ID 的 几种生成方案以及优缺点snowflake优化方案
在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID、退款ID等。那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十分重要的。下面我们一一来列举一…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
