工程化之旅 - 图1

前言

本文为前端技术大学课程:前端新人必修课-工程化 学习笔记,记录下来以后方便温故知新。

浅谈工程规范

为什么我们需要前端规范

我们可以先看下当一个团队中不同的成员的编码风格,Member A是指开发成员A同学,Member B是指开发成员B同学。

Last comma vs First comma

Member A喜欢编写Last comma风格,如下:

  1. var foo = 1,
  2. bar = 2,
  3. baz = 3;

Member B喜欢编写First comma风格,如下:

  1. var foo = 1
  2. ,bar = 2
  3. ,baz = 3;

统计数据表明,93.221%开发者喜欢把逗号放在句末,即Last comma风格。

Space vs Tab

日常编码过程中,Member A喜欢使用Tab键缩进,Member B喜欢使用空格键缩进。

Single quote vs Double quote

Member A喜欢编写Single quote风格,如下:

  1. var foo = 'bar'
  2. var obj = {'foo':'bar'}

Member B喜欢编写Double quote风格,如下:

  1. var foo = "bar"
  2. var obj = {"foo":"bar"}

如上所举出的3个Case中,我们可以看出,统一前端规范是非常有必要的,假如一个团队中,成员A编写的代码是A风格,成员B编写的是B风格,这样项目维护成本和团队协作的成本就太大了。
随着时间的发展,前端应用也变得越来越庞大和复杂,统一的前端规范变得非常重要,可以有效解决以下问题:

  • 沟通协调成本高
  • 应用维护成本高
  • 代码质量

    前端规范及配套的工具

  • stylelint-config-ali

  • eslint-config-ali
  • commitlint-config-ali
  • f2elint

    当研发流程遇上前端规范

    如下图示:研发的过程中,首先是有一套编码规约,在制定好规约的基础上,去接入配套的规范工具及IDE插件,代码提交前设置提交钩子卡口、代码发布前设置发布卡口。
    image.png

    Git相关

    版本控制

    版本控制是指一种记录一个或若干个文件变化,以便将来查询特定版本修订情况的系统。常用的有以下两种:

  • SVN - 集中化版本控制系统

  • Git - 分布式版本控制系统

两者区别:使用Git,开发人员不会因为贫乏的提交冲突而中断,管理人员无需为数据备份而担心。

Git原理

image.png

常用命令

命令 描述
git clone 克隆仓库
git add & git commit 提交代码
git status 查看工作目录状态
git log 显示提交日志
git checkout -b A 创建一个名称为A的新分支,并切换
git merge 分支合并
git push & git pull 推送分支到远程 | 拉取远程代码到本地
git diff 比较工作区和暂存区的区别

常用GUI工具

软件推荐:

  • SourceTree
  • TortoiseGit

VSCode插件推荐:

  • Git File History

image.png

  • GitLens

image.png

构建部署与发布

前端云构建

工程化之旅 - 图6
云构建优势:

  • 构建逻辑标准化
  • 环境纯净
  • 产物溯源
  • 满足不同团队需求
  • 支持本地&云开发

    构建器及其服务

    构建器完成了构建逻辑和代码逻辑的解耦,将项目本身中的自定义构建逻辑package.json拿出来,抽离成一个单独的npm包。
    image.png
    使用构建器缓存,可以减少10%-50%的构建时长。

    构建通用服务能力

  • Soucemap提取

image.png
如图,云构建完成后,会生成一个sourcemap,这个soucemap在构建产物中会被删除,外面是看不到的,这样会很安全。但是会在内网生成一个链接,通过链接可以访问到 sourcemap,可以在内网方便调试,有助于开发者排查线上问题。

  • 构建依赖扫描记录与分析

image.png
同样的代码,今天构建和明天构建,项目中某个包实际的依赖的版本可能会发生变化,某些分布式的包可能不会按照标准更新,这些变化可能会导致逻辑上或者安全上的问题,比如导致你项目中页面白屏等问题。所以产出构建产物的依赖,需要被记录下来, 需要和之前的版本进行对比分析,可以帮助你更好的定位分析问题。

任务调度系统

任务调度系统是支撑2000个/h的构建任务并发的核心,它负责容器的调度、基础镜像的管理以及管理日志等。
image.png

云构建扮演的角色

如下图,在整个前端工程体系中,云构建基础服务能力中承担着前端资源构建的角色。
image.png

打造愉快的前端应用

脚手架

概念

脚手架是一组最佳实践集合的基础模板,能够让你快速启动项目,而不用关心复杂的配置。

好处

  • 快速启动项目,无需关注项目配置
  • 规范各种目录结构和开发配置
  • 降低沟通成本和项目出错风险
  • 提高效率和项目可维护性

    常见的脚手架

  • create-react-app

  • Vue Cli
  • Umi

    组件化&模块化

    模块化

    模块化最重要的思想是分而自治。常见的模块化规范:

  • AMD

  • CMD
  • CommonJs
  • ES Module

    为什么模块化?

  • 命名冲突

  • 逻辑复杂
  • 依赖混乱

    组件化(UI层分治能力)

    页面中独立可交互的区域都可称之为组件,每个组件对应一个工程目录,每个组件所需要的资源都放在这个工程目录下做就近维护,如图中的header组件,header组件目录下的html、css、js、png等资源统一维护管理。组件化开发可以更方便团队间的协同。
    image.png

    体验监控系统

    体验监控系统包含哪些方面

    体验指标

    用户体验包含用户与公司的产品与服务交互中的所有面向,业界对体验指标主要分为两大类:主观和客观。
    主观包括:

  • 用户声音(反馈、工单等)

  • 用户调研(问券、访谈等)

客观包括:

  • 用户行为(点击率、转化率、跳失率等)
  • 系统表现(稳定性、流畅性)

    业界知名监控系统

  • Sentry

  • ARMS
  • Fundebug

    前端领域密切关注的表现层面

    稳定性:

  • 脚本异常

  • 接口异常
  • 资源异常
  • 白屏
  • Crash

流畅性:

  • 页面加载速度
  • 响应速度
  • 动画流畅性
  • 滚动流畅性
  • 卡顿

    体验监控系统怎么做

    监控系统架构

    image.png

    日志采集

  • 脚本异常(页面内发生的JS报错)

    1. // 采集页面脚本报错
    2. window.addEventListener('error',()=>{})
    3. // 采集未显式捕获的Promise异常
    4. window.addEventListener('unhandledrejection',()=>{})
  • 接口异常

通过重写XMLHttpRequest和fetch的原生方法来实现。

  • 资源异常

资源异常包含页面内图片、CSS、JS等Assets资源加载失败。

  1. window.addEventListener('error',(e)=>{
  2. // 排除JSERROR
  3. if(!(e instanceof ErrorEvent)) {
  4. // 资源路径
  5. e.target.src || e.target.href
  6. // 资源类型
  7. e.target.tagName
  8. }
  9. },true)
  • 白屏 | 方案 | 实现 | 优点 | 缺点 | | —- | —- | —- | —- | | 基于Native容器 | 页面加载完成后3秒页面还是全屏白色像素 | 不依赖JS、不丢点 | 依赖容器 | | 基于PaintTiming | 页面加载完成后3秒页面没有first-paint | 实现简单,不依赖容器;
    对页面性能几乎没有影响 | 兼容性差 | | 基于MutationObserver | 页面加载完成后3秒是否有节点变化 | 实现简单,不依赖容器 | 节点没变化不代表白屏 |

  • Crash

Crash是指页面因为内存溢出、死循环等原因导致崩溃的异常。

方案 实现 优点 缺点
基于Native容器 监控webview进程状态,发送Crash日志 不依赖JS、不丢点 依赖容器
基于Service Worker HTML请求进入SW后标记页面进行加载,页面每隔一定时间向SW发送一次心跳,一段时间没有发送心跳则认为页面Crash 不依赖容器
兼容性差;
SW侵入性强、风险高;
页面Pause后无法进行心跳检测
基于LocalStorage里的页面离开状态 在页面开始加载时标记开始加载,在pagehide、beforeunload时标记离开,二次进入页面时判断是否正常离开 不依赖容器;
兼容性较好
埋点发送滞后,起不到监控告警作用
  • 流畅性(加载性能) | 指标 | 采集方法 | | —- | —- | | load | NavigationTiming | | FCP | PerfermancePaintTiming | | LCP | PerfermancePaintTiming | | FID | PerfermanceEventTiming | | TTI | 无API,实验室环境使用LightHouse检测 | | TBT | 无API,实验室环境使用LightHouse检测 |

日志上报

不同的上报方式及优缺点:

方案 优点 缺点
IMG请求 兼容性 部分浏览器丢点,延迟页面卸载;
Get请求长度限制
Fetch/XHR 兼容性
Fetch丢点;
同步XHR不丢点,但延迟页面卸载
Navigator.sendBeacon() 不丢点;
不会延迟页面加载
兼容性

工程化体系最佳实践-build-scripts

工程构建的演进

工程化之旅 - 图14

工程架构设计

基础依赖依靠社区的最佳实践,如webpak、babel等,webpack-chain帮助开发者在上层修改webpack,插件体系可以帮助你扩展工程能力,提供配置文件build.json,最后提供3个对外命令即开发运行项目命令start、打包命令build和运行测试test命令。
image.png

工程生态

image.png

总结

综上,从前端规范开始说起,引出了一些规范工具(f2elint等),再结合到具体的研发流程中;对于Git版本管理、常用命令和GUI工具都比较基础;构建部署与发布中提到了云构建、通用服务能力、任务调度系统;体验监控主要是监控系统的日志采集和日志上报方式;工程化最佳实践主要是build-scripts架构设计和工程生态。

参考链接

https://f2e.alibaba-inc.com/markdown?spm=a2o8t.11089562.0.0.1a5e6654FpIz7Z&gitlab=f2e-specs%2Fstyle-guide%2F6.tools%2F1.tools.md

https://ata.alibaba-inc.com/articles/207276?spm=ata.21736010.0.0.5ab87536bQQ7xb