2024年前端最全我们是如何做好前端工程化和静态资源管理 - 無雄 - 博客园,2024年最新字节面试官职级

最后

今天的文章可谓是积蓄了我这几年来的应聘和面试经历总结出来的经验,干货满满呀!如果你能够一直坚持看到这儿,那么首先我还是十分佩服你的毅力的。不过光是看完而不去付出行动,或者直接进入你的收藏夹里吃灰,那么我写这篇文章就没多大意义了。所以看完之后,还是多多行动起来吧!

可以非常负责地说,如果你能够坚持把我上面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

根据页面组件化,通过工具分析,我们将获得页面与组件的依赖关系表,同时也能确认页面所引用资源的依赖关系,例如,我们在页面hello中同步引用组件topbar,那么依赖关系表中将会记录同步引用关系hello引用topbar.tpl、topbar.css、topbar.js,那么页面hello将会自动加载组件topbar的CSS与JS,同时依赖表会记录异步引用的关系,假如我们在组件C中通过API异步引用了组件D的js,那么会在依赖表中记录C异步引用D.js这一个依赖关系,这样D.js这个资源将会在用到的时候被异步调用。

组件依赖

资源依赖

同步引用的资源通过生成combo形式链接,在服务端进行文件合并,这样在页面加载的时候,页面只会加载自己需要的同步资源,异步的资源将会在用到的时候再加载,有效避免资源冗余。同时删除、增加组件也非常方便,只需改动模板中对组件调用,通过编译工具会自动重新生成模板以及combo链接。

我们可以将资源加载的操作抽离出来,形成一套统一的资源加载框架设计,这样我们使用的模板可以变得更加灵活,无论是纯html模板,还是PHP或Java之类的后端模板都能有效支持。编译工具扫描代码后只生成资源依赖表,我们通过实现各语言平台的资源加载框架,让不同语言的模板都能基于同一个资源依赖表进行资源加载。

同时,对资源进行MD5重命名处理,文件md5重命名也是一种提升性能的有效手段,使用文件md5后开启服务器强缓存,可以提升缓存的利用率并避免不必要的缓存判断处理。但文件md5重命名后会出现开发时引用的文件名对不上的问题,这就需要在资源表中记录原文件名与md5重命名后之间的对应关系,当我们引用一个资源时,就会通过查表获取重命名后的资源名,然后利用代码中引用资源定位的能力来进行资源名自动替换。

md5

静态资源预加载

所谓静态资源预加载,就是当用户在进行浏览页面的时候,我们可以在当前页面静默加载下一个页面的静态资源,这样当用户进入到下一个页面时就能快速打开页面,从而在不知不觉中提升页面的打开速度。

静态资源预加载设计

我们会在静态资源预加载平台上配置每一个页面id对应需要预加载页面资源的id,然后系统通过读取资源依赖表获取到所需要预加载的静态资源,生成预加载资源列表文件,再将文件推送到线上服务器,通过页面挂载js请求获取预加载资源列表,随后静默加载资源。在有了资源依赖表后,我们可以准确地分析到每一个页面引用资源的请求,就可以很好地实现静态资源预加载的功能。

静态资源预加载

Athena


工欲善其事,必现利其器。为了实现我们对提升开发效率和产品性能的诉求,我们提出了比较完整的工程化解决方案以及对应的工具Athena

Athena是由京东【凹凸实验室】(aotu.io) 推出的一套项目流程工具,通过Athena,我们可以很流程地跑完整个开发流程。Athena分为两部分,一是本地自动化编译工具,二是资源管理平台,其架构如下

Athena

本地自动化工具

Athena本地编译工具是一个基于NodeJs的命令行工具,通过执行命令的方式来优化我们的开发流程,目前Athena的主要功能有

  • 自动创建项目、模块、页面、组件结构

  • 轻量组件化功能,根据组件加载情况生成资源依赖表

  • Sass/less 编译

  • 代码检查

  • CSS prefix等处理

  • CSS合并压缩,JS合并压缩

  • 自动生成雪碧图,自动多倍图,图片压缩

  • 字体文件压缩

  • 自定义图片转base64

  • 文件内联,可以内联样式及JS代码

  • 文件MD5戳,将文件进行使用MD5进行重命名

  • 本地预览,直接查看整个项目

  • 资源定位(图片等资源路径替换)

  • 生成CSS页面片,提供将页面引用的CSS/JS抽离成页面片的形式,方便管理CSS资源

  • 部署到预览机和开发机

创建项目结构

在执行创建命令时,Athena会从管理平台下载自定义好的项目模板,可以根据模板创建项目、模块、页面、和组件。Athena有四个创建命令:

通过执行 $ ath app demo 命令就可以生成定义好目录结构的项目。

创建项目

随后可以通过 $ ath module home来创建一个业务模块;

通过 $ ath page index 来创建页面;

通过 $ ath widget widgetName 来创建组件。

开发使用

组件化

Athena中实现组件化主要是分为两种,一是针对纯HTML模板,通过扩展模板引擎方法实现,提供了组件化API widget.load,它可以方法接收三个参数,第一个参数是widget的名称,后面两个参数是可选参数,第二个是向widget传递的一些参数,第三个是widget所属的模块,如果是本模块,可以不传例如

1

2

3

4

5

6

7

<%= widget.load('user') %>

<%=

widget.load('user', {

param: 'test'

})

%>

<%= widget.load('user', null, 'gb') %>

通过模板引擎编译,执行widget.load方法,可以实现加载模板,记录依赖关系的目的。

组件化形式

二是针对不同语言的后端模板,通过实现各自的组件化框架来进行组件的加载,例如 PHP 下使用 <?= $widget->load('user', NULL, 'gb') ?> 来进行组件加载,再通过代码扫描得出组件依赖关系。

Athena中的API

Athena针对模板提供了一系列的API来扩展丰富的功能,例如前面提到的 <%= widget.load() %> 来实现组件化。

同时Athena中还提供了其他API:

<%= getCSS() %><%= getJS() %> 用来引用CSS/JS文件,传入文件名和模块名;

<%= uri() %> 提供了资源定位功能,可以在模板中标记资源,编译过程中会进行替换,而且在JS中也有资源定位API __uri()

<%= inline() %> 提供了内联资源的功能,传入文件名和模块名,可以在模板中内联任意资源,例如图片以及JS脚本;而且 inline 也可以内联一段网络资源,例如线上的JS文件,同样的在JS中也有内联资源API __inline()

雪碧图标识 ?__sprite ,在CSS中引用图片最后加上标识 ?__sprite 可以自动生成自定义名称雪碧图,同时支持自定义生成多张雪碧图,只需要要标识后面带上一个文件名,就可以生成一张以这个文件名来命名的雪碧图,例如 ?__sprite=icons ,这样所有带同样标识的图片就会生成一张以 icons 为文件名的雪碧图。

编译预览

编译任务

在编写完项目,就可以通过命令来对项目进行编译了,执行编译命令 $ ath build,会针对指定模块执行已经定义好的编译任务,根据项目需求,目前编译都是基于业务模块去编译,编译任务的最小执行单位是页面,每次编译都会执行以下编译列表

编译任务

编译截图

本地预览

执行预览命令 $ath serve 会执行精简版编译任务来编译项目,编译完项目后会生成一份站点地图,随后打开一个本地服务器来预览项目,使用这个命令可以很方便地进行开发,在预览时会同时watch目录和文件的改动,并且提供了livereload功能,我们可以在预览时任意修改文件,都将实时地反映到页面中,同时可以新建另一个窗口执行新增组件和页面的操作,让整个开发过程非常顺畅,我们只需关注开发本身就好,不需要再关注其他事。

ath serve

执行完编译任务后,默认自动打开浏览器,预览站点地图

站点地图

Mock server

在进行项目预览的同时,Athena同时提供了mock data的服务,我们可以配置相应的路由,以及路由接口对应的假数据,所有的接口请求会发送到mock server上,在mock server中可以选择将请求代理到假数据平台还是代理到线上接口,这样就可以脱离后端进行开发联调了,以此实现数据的前后端分离。

mock server

项目部署

在开发预览完后,通过命令 $ ath publish 就可以将项目发布到配置好的测试机上,发布同时支持ftp、sftp以及http形式。

组件维护

我们通过组件化的手段已经将我们的项目进行组件化了,这样我们经过业务迭代积累,产出很多业务公共组件,但在以往的项目开发中,公共组件的更新与维护一直很受限制,而且有哪些公共组件、公共组件长什么样子,只能依靠口口相传或者手工维护的文档。所以在Athena中我们加入了组件平台,在组件平台上统一展示各个业务的公共组件,而得益于本地工具,组件平台不需要人工干预维护,我们可以在本地通过命令 $ ath widget-publish [widgetName] 命令来发布一个组件到组件平台,这样其他人就可以立即在组件平台进行组件的预览,而其他人若想使用该组件时,在本地通过命令 ath widget-load [widgetId] 就可以下载该组件到自己的模块目录下了。

这样组件的维护更加自动化,公共组件的使用也更加方便了。

组件发布

组件发布

组件下载

组件下载

自身优化

为了提升开发效率,Athena做了一些优化操作

精简项目预览时的任务

在开发时进行项目预览时,会执行精简版的编译任务,剔除了类似文件压缩、雪碧图生成、模板抽离处理等耗时的操作,只保留核心、必须的编译任务,这样可以极大地减少编译时间,提升开发的效率。

预览时监听细化

在开发进行预览时,会对所有文件的改动进行监听,而针对每一类文件都有非常细化的操作,当文件改动时只会执行改文件所需要的编译任务,而不会进行整体编译,这样可以很好地提升开发效率。例如改动某一组件的CSS文件,则只会针对该文件执行一些相关的CSS操作。

同时得益于所有文件依赖关系的记录,在监听时会根据依赖关系进行文件编译,例如某sass文件中引入了另一个sass库文件,修改这个sass库文件的时候,会根据引用关系表同时更新到所有引用到这个sass文件的文件,这样项目文件更新及时,让开发流程更加流畅。

编译缓存

在图片压缩和sass编译时,开启文件缓存,将已经编译过且没有改动的文件过滤掉,不再编译,大幅提升编译速度。

发布缓存

设置发布过滤,根据文件md5过滤掉已经发布过的文件,提升发布速度。

技术选型

Athena本地工具早期技术选型是 Yeoman + Gulp 的方式,但后来由于安装、更新非常麻烦,命令太长很难打的原因,我们改成了自己开发一个全局安装包的方式,编译核心使用的还是 Gulp 的 vinyl-fs 来实现文件流处理,通过 ES6 Promise 来进行编译流程控制,最小以页面为单位,经过一系列编译任务,最后产出编译好的文件。

技术选型

管理平台

性能优化一直是前端工程师探索的课题,很多时候就是资源的分配问题,也就是资源管理。为了更好地配合本地构建工具来管理资源,我们搭建了管理平台。我们来看下,结合本地构建工具和管理平台,工作流程变成了怎样?

工作流程

  1. 在管理平台上创建项目,输入项目名称和预览机,以及选择相应的模板等;

  2. 在终端执行ath app指令,工具会优先拉取远程服务器的项目信息来初始化项目,如果没有获取到相关信息,就会在本地生成项目,并将项目信息上报给服务器;

  3. 项目初始化后,就可以创建模块、页面、组件了;

  4. 在编码过程中,可通过ath server预览页面;

  5. 在本地通过后,可执行ath publish将代码发布到开发机或者预览机。

在上面的publish指令中,工具会扫描所有文件,执行代码检查,扫描页面文件,获取组件依赖关系,根据组件依赖关系进行文件合并,然后会进行样式处理、js处理以及图片的处理,根据配置是否进行md5重命名文件,组装html,插入样式、js和图片,最后将编译好的文件发布到相应的机器。在整个过程里面,会生成资源关系依赖表,最终会将资源关系表及编译后的文件上传至管理平台。

除此之外,每个指令的操作都会上报给管理平台。管理平台收到数据后,会对数据进行处理,最终可以在平台上看到项目相关的信息。

整体工作流程图如下:

工作流程

从上面的工作流程中,我们可以看到,管理平台需要有数据统计、资源管理以及项目管理的功能。整体架构图如下:

管理平台架构

数据统计

数据统计包含项目操作日志,主要是用于统计团队每个成员具体的操作,方便项目成员查看项目代码变更;另一部份是统计样式表、脚本以及图片的压缩数据,用于显示工具给我们项目带来的提升。

以下是操作日志统计:

数据统计

资源管理

资源管理是管理平台的核心,主要分为4个部分:模块展示、依赖关系、组件预览和权限控制。这部分功能主要通过本地构建工具提供的资源关系表来完成。

模块展示

模块展示,用于记录项目具体包含哪些模块以及模块具体的信息。在平常开发中,我们的项目会分为许多模块,不同的模块有不同的人来开发和维护。当项目越大的时候,可以通过管理平台清晰地看到模块具体的信息。

模块展示

依赖关系

依赖关系,主要是html、css、js和图片相互之间的关系。通过分析资源关系依赖表,可以获取到各个资源被引用的情况以及线上版本的情况。当线上环境采用md5来做资源管理时,我们不是很清晰地知道静态资源对应线上哪个版本的资源,而有了这个依赖关系表,当出现问题时,我们可以更快地定位到具体的资源。

依赖关系

组件管理

我们采用组件来拼凑页面,当项目越大时,组件越多,那么如何管理组件成为了一个棘手的问题。比如说,有一些比较老的冗余组件,我们不确定是否为其他页面所引用,那么就不能愉快地删除它。有了组件管理,可以清晰地知道组件的被调用情况,就可以对组件做相应的操作。

这里分享一份由字节前端面试官整理的「2021大厂前端面试手册」,内容囊括Html、CSS、Javascript、Vue、HTTP、浏览器面试题、数据结构与算法。全部整理在下方文档中,共计111道

HTML

  • HTML5有哪些新特性?

  • Doctype作⽤? 严格模式与混杂模式如何区分?它们有何意义?

  • 如何实现浏览器内多个标签页之间的通信?

  • ⾏内元素有哪些?块级元素有哪些? 空(void)元素有那些?⾏内元 素和块级元素有什么区别?

  • 简述⼀下src与href的区别?

  • cookies,sessionStorage,localStorage 的区别?

  • HTML5 的离线储存的使用和原理?

  • 怎样处理 移动端 1px 被 渲染成 2px 问题?

  • iframe 的优缺点?

  • Canvas 和 SVG 图形的区别是什么?

JavaScript

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 问:0.1 + 0.2 === 0.3 嘛?为什么?

  • JS 数据类型

  • 写代码:实现函数能够深度克隆基本类型

  • 事件流

  • 事件是如何实现的?

  • new 一个函数发生了什么

  • 什么是作用域?

  • JS 隐式转换,显示转换

  • 了解 this 嘛,bind,call,apply 具体指什么

  • 手写 bind、apply、call

  • setTimeout(fn, 0)多久才执行,Event Loop

  • 手写题:Promise 原理

  • 说一下原型链和原型链的继承吧

  • 数组能够调用的函数有那些?

  • PWA使用过吗?serviceWorker的使用原理是啥?

  • ES6 之前使用 prototype 实现继承

  • 箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?

  • 事件循环机制 (Event Loop)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值