FE Architecture
文章平均质量分 93
前端架构
Wang's Blog
Keep learning for the innovation era.
展开
-
Vite: 近几个版本的更新
在 2021 年 2 月,尤大正式推出了 Vite 2.0 版本,可以说是 Vite 的一个重要转折点,自此之后 Vite 的用户量发生了非常迅速的增长,很快达到了每周 100 万的 npm 下载量。同时,Vite 的社区也越来越活跃,目前已经形成非常庞大的社区生态(详情可见Github 地址),给整个前端领域带来了诸多的改变,如:Nuxt 3、SvelteKit、Astro、StoryBook 等在内的各大前端框架已经将 Vite 作为内置的构建方案。原创 2024-07-05 23:45:00 · 870 阅读 · 0 评论 -
Vite: Bundler实现代码打包、Tree Shaking
前文,我们实现了一个简单的 JavaScript AST 解析器,对词法分析和语法分析底层原理有了一定的了解现在,我们将基于 AST 解析器来实现一个模块打包工具(Bundler),也就是实现一个精简版的 Rollup模块 AST 解析模块依赖图生成模块拓扑排序基于符号可达性的 Tree ShakingBundle 代码生成。原创 2024-07-05 20:30:00 · 578 阅读 · 0 评论 -
Vite: Bundler实现JavaScript的AST解析器—词法分析、语义分析
基于前文,我们写了一个迷你版的 no-bundle 开发服务,也就是 Vite 开发阶段的 Dev Server,而在生产环境下面,处于页面性能的考虑,Vite 还是选择进行打包(bundle),并且在底层使用 Rollup 来完成打包的过程。接下来,我们实现一个 JavaScript Bundler,理解生产环境下 Vite/Rollup 的模块打包究竟是如何实现的。原创 2024-07-05 12:30:00 · 558 阅读 · 0 评论 -
Vite: 实现 no-bundle 开发服务 (2)
基于前文Vite: 实现 no-bundle 开发服务 (1)我们基于下面的导图继续实现 no-bundle 构建服务CSS 编译插件静态资源加载插件模块依赖图开发,并在 transform 中间件中接入HMR 服务端代码开发HMR 客户端代码开发。原创 2024-07-05 07:15:00 · 554 阅读 · 0 评论 -
Vite: 实现 no-bundle 开发服务 (1)
在前文中,我们系统了解了 Vite 的实现源码,从配置解析、依赖预构建、插件流水线和 HMR 这几个方面带你完整的梳理了 Vite 的底层原理,现在,我们将进一步,用实际的代码来写一个迷你版的 Vite,主要实现 Vite 最核心的 no-bundle构建服务。现在我们深入地理解代码层面的实现细节,拥有独立开发一个 no-bundle 构建工具的能力。原创 2024-07-05 03:00:00 · 954 阅读 · 0 评论 -
Webpack: HMR动态替换页面代码原理
HMR 全称 Hot Module Replacement,可以翻译为「模块热更新」,最初由 Webpack 设计实现,至今已几乎成为现代工程化必备工具之一,它能够在保持页面状态不变的情况下动态替换、删除、添加代码模块,提供超级丝滑顺畅的 Web 页面开发体验。对于复杂表单场景,这意味着你可能需要重新填充非常多字段信息;弹框消失,你必须重新执行交互动作才会重新弹出。再小的改动,例如更新字体大小,改变备注信息都会需要整个页面重新加载执行,整体开发效率偏低。原创 2024-07-04 23:45:00 · 590 阅读 · 0 评论 -
Webpack: 基于Sourcemap源码映射原理与使用技巧
Sourcemap 协议最初由 Google 设计并率先在 Closure Inspector 实现,它的主要作用就是将经过压缩、混淆、合并的产物代码还原回未打包的原始形态,帮助开发者在生产环境中精确定位问题发生的行列位置,例如:在 Webpack 内部,这段生成 Sourcemap 映射数据的逻辑并不复杂,一句话总结:在钩子遍历产物文件assets数组,调用提供的map方法,最终计算出asset与源码之间的映射关系。原创 2024-07-04 20:30:00 · 937 阅读 · 0 评论 -
Webpack: Tree-shaking 删除无用模块
从前文,我们了解到 Webpack 从模块解析,到 Chunk 封装,到合并生成最终 Bundle 整个运行过程,接下来我们可以开始关注一些高频使用功能的底层实现,加深理解。例如,Tree-Shaking 就是一个不错的例子,它能充分优化产物代码,使用频率颇高,并且底层实现逻辑比较复杂,需要持续读取、修改 ModuleGraph 对象的状态;需要通过函数定制打包结果,等等,实现逻辑几乎贯穿了 Webpack 整个构建过程。原创 2024-07-04 12:45:00 · 953 阅读 · 0 评论 -
Webpack: 模块编译打包及运行时Runtime逻辑
回顾最近几节内容,Webpack 运行过程中首先会根据Module之间的引用关系构建对象;接下来按照若干内置规则将Module组织进不同Chunk对象中,形成ChunkGraph关系图。接着,构建流程将来到最后一个重要步骤:生成产物代码,这个过程会将所有Module内容一一转换为适当的产物代码形态,并以Chunk为单位合并Module产物代码,之后根据Module中出现的特性依赖,补充相应运行时代码,最终构建出我们日常所见的 Webpack Bundle 代码文件。原创 2024-07-04 07:45:00 · 946 阅读 · 0 评论 -
Webpack: 三种Chunk产物的打包逻辑
在前文Webpack: Dependency Graph 管理模块间依赖中,我们已经详细讲解了「构建」阶段如何从 Entry 开始逐步递归读入、解析模块内容,并最终构建出模块依赖关系图 —— ModuleGraph 对象。本文我们继续往下,讲解在接下来的「封装」阶段,如何根据 ModuleGraph 内容组织 Chunk,并进一步构建出 ChunkGroup、ChunkGraph 依赖关系对象的主流程。Chunk、ChunkGroup、ChunGraph 对象分别是什么?互相之间存在怎样的交互关系?原创 2024-07-04 04:15:00 · 1547 阅读 · 0 评论 -
Vite: 基于 ESM 的毫秒级 HMR 热更新的实现
基于 HMRBoundary (HMR 边界)的更新模式,即当一个模块发生变动时,Vite 会自动寻找更新边界,然后更新边界模块,如下图所示:那么,在 Vite 内部,服务端究竟是如何定位到 HMR 边界模块,以及客户端是如何接受更新并加载最新模块内容的现在, 探索下Vite 的底层实现,梳理 HMR 的各个实现要点,深入认识下 Vite 的 HMR 实现原理需要重点掌握 Vite 中的模块依赖图实现、服务端收集更新模块和客户端派发更新的原理。原创 2024-07-04 01:45:00 · 553 阅读 · 0 评论 -
Vite: 插件流水线之核心编译能力
Vite 在开发阶段实现了一个按需加载的服务器,每一个文件请求进来都会经历一系列的编译流程,然后 Vite 会将编译结果响应给浏览器。在生产环境下,Vite 同样会执行一系列编译过程,将编译结果交给 Rollup 进行模块打包这一系列的编译过程指的就是 Vite 的插件工作流水线(Pipeline),而插件功能又是 Vite 构建能力的核心,因此谈到阅读 Vite 源码,我们永远绕不开插件的作用与实现原理。原创 2024-07-03 22:45:00 · 1058 阅读 · 0 评论 -
Webpack: Dependency Graph 管理模块间依赖
Dependency Graph 概念来自官网一文,原文解释:dependencybundles大意:Webpack 处理应用代码时,会从开发者提供的entry开始递归地组建起包含所有模块的,之后再将这些module打包为bundles。然而事实远不止官网描述的这么简单,Dependency Graph 贯穿 Webpack 整个运行周期,从「构建阶段」的模块解析,到「生成阶段。原创 2024-07-03 19:30:00 · 995 阅读 · 0 评论 -
Webpack: 核心流程之Init、Make、Seal
在前文中,我们了解了 Webpack 的基本应用、性能优化、Loader 与 Plugin 组件开发方方面面的知识,相信学习过这些内容之后,你已经对 Webpack 有相当深入的理解了,可以开始从更底层的视角,自底向上重新审视 Webpack 实现原理。JavaScript,也就是所谓的静态模块打包能力。原创 2024-07-03 12:45:00 · 1358 阅读 · 0 评论 -
Webpack: 插件架构之Hook体系
Webpack 之所以能够应对 Web 场景下极度复杂、多样的构建需求,关键就在于其健壮、扩展性极强的插件架构,而插件架构的精髓又在于其灵活多变的 Hook 体系,可以说,只有真正掌握 Hook 底层设计与实现逻辑,深入理解不同 Hook 的运行特性与用法,才能灵活处理各种问题,更快更好地编写出 Webpack 插件。原创 2024-07-03 07:45:00 · 1021 阅读 · 0 评论 -
Webpack: 插件开发之提升插件健壮性
前文中,我们了解了 Webpack 插件的开发方式与基本架构逻辑,并结合若干开源项目剖析插件中如何与 Webpack 上下文交互,从而修改构建逻辑,实现插件功能需求。如何正确处理插件日志;如何上报统计信息,帮助用户更好了解插件的运行情况;如何借助校验配置参数;如何搭建自动测试环境。我们应该尽量复用 Webpack Infrastructure Logging 接口记录插件运行日志若插件运行耗时较大,应该通过接口上报执行进度,供用户了解运行状态应该尽可能使用。原创 2024-07-03 03:30:00 · 912 阅读 · 0 评论 -
Webpack: 剖析插件基本形态与架构逻辑
Webpack 对外提供了 Loader 与 Plugin 两种扩展方式,其中 Loader 职责比较单一,开发方法比较简单容易理解;Plugin 则功能强大,借助 Webpack 数量庞大的 Hook,我们几乎能改写 Webpack 所有特性,但也伴随着巨大的开发复杂度。学习如何开发 Webpack 插件并不是一件简单的事情,所以我打算用 3 个连续的章节,力求足够全面地剖析如何开发一款成熟、稳定的插件。原创 2024-07-02 23:45:00 · 722 阅读 · 0 评论 -
Webpack: Loader开发 (2)
在上一篇文章中,我们已经详细了解了开发 Webpack Loader 需要用到的基本技能,包括:Loader 基本形态、如何构建测试环境、如何使用 Loader Context 接口等。接下来我们继续拓展学习一些 Loader 辅助工具,包括:了解,并使用拼接文件名;了解,以及其背后的ajv库与 JSON-Schema 协议,学习使用实现参数校验文章最后还会深入剖析vue-loader组件源码,通过实战方式帮助大家更深入理解:如何开发一个成熟 Loader使用与。原创 2024-07-02 21:45:00 · 711 阅读 · 0 评论 -
Webpack: Loader开发 (1)
如何扩展 Webpack?有两种主流方式,一是 Loader —— 主要负责将资源内容翻译成 Webpack 能够理解、处理的 JavaScript 代码;二是 Plugin —— 深度介入 Webpack 构建过程,重塑构建逻辑。相对而言,Loader 的职责更单一,入门成本相对较低。我们关注以下的基础Loader 的基本形态与输入输出如何使用 Loader Context 上下文接口,并结合一些知名开源项目展开介绍部分常用接口如何为 Loader 编写自动测试代码。原创 2024-07-02 19:45:00 · 1650 阅读 · 0 评论 -
Vite: 深入依赖预构建与Esbuild
在 Vite 依赖预构建的底层实现中,大量地使用到了 Esbuild 这款构建工具,实现了比较复杂的 Esbuild 插件,同时也应用了诸多 Esbuild 使用技巧。我们现在了解下 Vite 预构建 神秘的面纱,从核心流程到依赖扫描、依赖打包的具体实现,来彻底理解预构建背后的技术,Vite 是如何灵活运用 Esbuild,将Esbuild 这个打包工具玩出花样预构建的核心流程,包括缓存判断、依赖扫描、依赖打包和元信息写入磁盘这四个主要的步骤,从宏观上对 Vite 预构建流程有了初步的认识。原创 2024-07-02 12:45:00 · 1336 阅读 · 0 评论 -
Vite: 配置解析服务
我们为什么要去读源码?原因主要有两个:一是加深对框架本身的理解,在面对一些项目的疑难杂症时,排查问题效率会更高;二是在遇到类似的开发场景时,可以举一反三,借鉴某个框架源码的实现思路,将技巧应用到其它的项目中我们看下Vite 配置解析服务的源码部分。Vite 构建环境分为 开发环境 和 生产环境 ,不同环境会有不同的构建策略,但不管是哪种环境,Vite 都会首先解析用户配置。那接下来,我就与你分析配置解析过程中 Vite 到底做了什么。原创 2024-07-02 07:00:00 · 966 阅读 · 0 评论 -
Vite: 项目性能优化
性能优化是前端工程化中老生常谈的话题,随着项目越来越庞大,稍不注意就会产生明显的性能问题。而在不同的场景中,我们对于项目性能的关注点是不一样的。在项目开发阶段,我们更关注开发体验,注重项目构建性能;而在生产环境中,我们一般更看重项目在的线上运行时性能。关于开发阶段的构建性能问题,Vite 内部已经做了相当多的优化,实现了项目秒级启动与毫秒级热更新,这部分的具体实现就不属于本文讨论的范畴了,本文所介绍的性能优化主要指线上环境的项目加载性能优化,与页面的 FCP、TTI 这些指标息息相关。原创 2024-07-02 03:00:00 · 670 阅读 · 0 评论 -
Webpack: 其他性能优化
前面章节我们已经详细探讨 Webpack 中如何使用分包、代码压缩提升应用执行性能。使用动态加载,减少首屏资源加载量;使用externals、Tree-Shaking、Scope Hoisting 特性,减少应用体积;正确使用[hash]占位符,优化 HTTP 资源缓存效率,等等。下面我们一一展开,解释每条最佳实践以及背后的逻辑。压缩、Tree-Shaking、Scope Hoisting 都在减少产物体积;Code Splitting、外置依赖、[hash]则有助于提升 HTTP 缓存效率;原创 2024-07-01 23:45:00 · 640 阅读 · 0 评论 -
Webpack: Terser与代码压缩
代码压缩是指在不改变代码功能的前提下,从声明式(HTML、CSS)或命令式(JavaScript)语言中删除所有不必要的字符(备注、变量名压缩、逻辑语句合并等),减少代码体积的过程,这在 Web 场景中能够有效减少浏览器从服务器获取代码资源所需要消耗的传输量,降低网络通讯耗时,提升页面启动速度,是一种非常基础且性价比特别高的应用性能优化方案。原创 2024-07-01 21:45:00 · 1829 阅读 · 0 评论 -
Webpack: 使用 SplitChunks提升应用性能
页面初始代码包过大,影响首屏渲染性能;无法有效应用浏览器缓存,特别对于 NPM 包这类变动较少的代码,业务代码哪怕改了一行都会导致 NPM 包缓存失效。为此,Webpack 提供了插件,专门用于根据产物包的体积、引用次数等做分包优化,规避上述问题,特别适合生产环境使用。不过,的使用方法比较复杂,我们得从 Chunk 这个概念开始说起。是 Webpack 4 之后内置实现的最新分包方案,与 Webpack3 时代的。原创 2024-07-01 19:45:00 · 1012 阅读 · 0 评论 -
Webpack: 构建优化
前面章节我们已经详细探讨 Webpack 中如何借助若干工具分析构建性能,以及如何使用缓存与多进程能力提升构建性能的基本方法与实现原理,这两种方法都能通过简单的配置,极大提升大型项目的编译效率。使用最新版本 Webpack、Node;配置resolve控制资源搜索范围;针对 npm 包设置跳过编译步骤;等等。下面我们一一展开,解释每条最佳实践以及背后的逻辑。原创 2024-07-01 12:45:00 · 900 阅读 · 0 评论 -
Webpack: 并行构建
HappyPack:多进程方式运行资源加载(Loader)逻辑;:Webpack 官方出品,同样以多进程方式运行资源加载逻辑;:多进程方式运行多个 Webpack 构建实例;:支持多进程方式执行代码压缩、uglify 功能。这些方案的核心设计都很类似:针对某种计算任务创建子进程,之后将运行所需参数通过 IPC 传递到子进程并启动计算操作,计算完毕后子进程再将结果通过 IPC 传递回主进程,寄宿在主进程的组件实例,再将结果提交给 Webpack。原创 2024-07-01 07:45:00 · 563 阅读 · 0 评论 -
Vite: 高阶特性 & Pure ESM
ESM 已经逐步得到各大浏览器厂商以及 Node.js 的原生支持,正在成为主流前端模块化方案。而 Vite 本身就是借助浏览器原生的 ESM 解析能力( type=“module” )实现了开发阶段的 no-bundle ,即不用打包也可以构建 Web 应用。原创 2024-06-30 23:00:00 · 920 阅读 · 0 评论 -
Vite: 模块联邦实现跨应用代码共享
在 2020 年上半年,Webpack 提出了一项非常激动人心的特性—— Module Federation (译为 模块联邦 ),这个特性一经推出就获得了业界的广泛关注,甚至被称为前端构建领域的 Game Changer。实际上,这项技术确实很好地解决了多应用模块复用的问题,相比之前的各种解决方案,它的解决方式更加优雅和灵活。原创 2024-06-30 19:30:00 · 702 阅读 · 0 评论 -
Vite: 预渲染与高可用SSR
在非常早期的 Web 技术中,大家还是使用 JSP 这种古老的模板语法来编写前端的页面,然后直接将 JSP 文件放到服务端,在服务端填入数据并渲染出完整的页面内容,可以说那个时代的做法是天然的服务端渲染。但随着 AJAX 技术的成熟以及各种前端框架(如Vue、React)的兴起,前后端分离的开发模式逐渐成为常态,前端只负责页面 UI 及逻辑的开发,而服务端只负责提供数据接口,这种开发方式下的页面渲染也叫 客户端渲染(Client Side Render,简称 CSR)。原创 2024-06-30 15:45:00 · 779 阅读 · 0 评论 -
Webpack: 持久化缓存大幅提升构建性能
缓存是一种应用非常广泛性能优化技术,在计算机领域几乎无处不在,例如:操作系统层面 CPU 高速缓存、磁盘缓存,网路世界中的 DNS 缓存、HTTP 缓存,以及业务应用中的数据库缓存、分布式缓存等等。那自然而然的,我们也可以在 Webpack 使用各式各样的缓存技术,通过牺牲空间来提升构建过程的时间效率,在这篇文章中,我将从 Webpack5 的持久化缓存开始介绍用法、性能收益、基本原理;之后再过渡到 Webpack4 中如何借助第三方组件(Loader、Plugin)实现持久化缓存。原创 2024-06-30 12:45:00 · 1207 阅读 · 0 评论 -
Webpack: 7 款常用的性能分析工具
Webpack 最大的优势在于它的功能非常强大、全面,加之繁荣活跃的组件生态,已经足够应对几乎所有 Web 构建需求,包括:SPA、MPA、SSR、桌面应用、Node 程序、WebAssemsbly、PWA、微前端等等,所以即使在近几年工程化领域异军突起、百花齐放的背景下,Webpack 也依然能保持老大哥的位置。但软件世界没有银弹!Webpack 在大型项目中通常性能表现不佳,这一方面是因为 JavaScript 语言的单线程架构决定了 Webpack 的运算效率就不可能很高;原创 2024-06-30 06:00:00 · 988 阅读 · 0 评论 -
Webpack: 核心配置结构
Webpack 是一种「配置」驱动的构建工具,所以站在应用的角度,必须深入学习 Webpack 的各项配置规则,才能灵活应对各种构建需求。剖析配置结构规则,解释对象、数组、函数三种形态的写法,以及各自应对的场景;详细讲解环境治理的意义,以及如何借助多文件实现环境治理;,帮助你更深入理解配置规则。Webpack 配置文件支持导出对象、数组、函数三种形态,其中对象形式最为常用,足够应对多数业务项目场景;数组形式适用于需要为同一份代码同时构建多种产物的场景,如 NPM Library;原创 2024-06-30 03:30:00 · 739 阅读 · 0 评论 -
Webpack: 深入理解图像加载原理与最佳实践
图形图像资源是当代 Web 应用的最常用、实惠的内容、装饰元素之一,但在 Webpack 出现之前对图像资源的处理复杂度特别高,需要借助一系列工具(甚至 Photoshop)完成压缩、雪碧图、hash、部署等操作。而在 Webpack 中,图像以及其它多媒体资源都被提升为一等公民 —— 能够像引用普通 JavaScript 模块一样通过语句导入资源模块,这种开发模式允许我们将图像相关的处理合入统一的心智模型中,提升开发效率。如何使用适当的 Loader 处理图像资源;原创 2024-06-29 23:45:00 · 1195 阅读 · 1 评论 -
Webpack: 开发 PWA、Node、Electron 应用
毋庸置疑,对前端开发者而言,当下正是一个日升月恒的美好时代!在久远的过去,Web 页面的开发技术链条非常原始而粗糙,那时候的 JavaScript 更多用来点缀 Web 页面交互而不是用来构建一个完整的应用。直到 2009年5月Ryan Dahl正式发布 NodeJS,JavaScript 终于有机会脱离 Web 浏览器独立运行,随之而来的是,基于 JavaScript 构建应用程序的能力被扩展到越来越多场景,我们得以用相同的语言、技术栈、工具独立开发桌面端、服务端、命令行、微前端、PWA 等应用形态。原创 2024-06-29 22:00:00 · 1085 阅读 · 0 评论 -
Webpack: 构建微前端应用
Module Federation 是 Webpack 5 新引入的一种远程模块动态加载、运行技术,虽然国内讨论热度较低,但使用简单,功能强大,非常适用于微前端或代码重构迁移场景。使用上,只需引入插件,按要求组织、分割好各个微应用的代码,并正确配置配置项即可实现基于 HTTP(S) 的模块共享功能。此外,我们还可以通过插件的shared配置项实现在应用间共享基础依赖库,还可以通过等一系列配置,精细控制依赖的共享版本与范围。原创 2024-06-29 18:45:00 · 1183 阅读 · 0 评论 -
Webpack: 构建 NPM Library
虽然 Webpack 多数情况下被用于构建 Web 应用,但与 Rollup、Snowpack 等工具类似,Webpack 同样具有完备的构建 NPM 库的能力。正确导出模块内容;不要将第三方包打包进产物中,以免与业务方环境发生冲突;将 CSS 抽离为独立文件,以方便用户自行决定实际用法;始终生成 Sourcemap 文件,方便用户调试。本文将从最基础的 NPM 库构建需求开始,逐步叠加上述特性,最终搭建出一套能满足多数应用场景、功能完备的 NPM 库构建环境。使用配置项,正确导出模块内容;原创 2024-06-29 14:30:00 · 823 阅读 · 0 评论 -
Vite: Polyfill 解决低版本浏览器的兼容问题
谈到 Vite,可能很多人都觉得这是一个现代前端构建工具,应该在现代浏览器中使用,放到各种语法特性都缺失的低版本浏览器(如 ie 11 )就不适用了。这种观念对不对呢?首先跟大家抛出结论: 通过 Vite 构建我们完全可以兼容各种低版本浏览器,打包出既支持现代( Modern ) 浏览器又支持旧版( Legacy )浏览器的产物。接下里的课程中,我就来与你分析一下为什么在 Vite 中能够彻底解决低版本浏览器的兼容性问题,以及通过什么手段解决,需要借助哪些 JS 的工具和生态。原创 2024-06-29 12:45:00 · 1056 阅读 · 0 评论 -
Vite: 代码分割与拆包
在生产环境下,为了提高页面加载性能,构建工具一般将项目的代码打包(bundle)到一起,这样上线之后只需要请求少量的 JS 文件,大大减少 HTTP 请求。当然,Vite 也不例外,默认情况下 Vite 利用底层打包引擎 Rollup 来完成项目的模块打包。某种意义上来说,对线上环境进行项目打包是一个必须的操作。但随着前端工程的日渐复杂,单份的打包产物体积越来越庞大,会出现一系列应用加载性能问题,而代码分割可以很好地解决它们。原创 2024-06-29 07:00:00 · 1019 阅读 · 0 评论 -
Vite: 毫秒级局部更新之HMR
在代码变更之后,如何实时看到更新后的页面效果呢?在很久之前的方案是通过 live reload也就是自动刷新页面的方式来解决的。不过随着前端工程的日益庞大,开发场景也越来越复杂,这种 live reload 的方式在诸多的场景下却显得十分鸡肋,简单来说就是 模块局部更新 + 状态保存 的需求在 live reload 的方案没有得到满足,从而导致开发体验欠佳。原创 2024-06-28 20:00:00 · 744 阅读 · 0 评论