鼎信诺审计前端取数工具_给2019前端的5个建议

2019 农历新年即将到来,是时候总结一下团队过去一年的技术沉淀。过去一年我们支撑的数据相关业务突飞猛进,其中两个核心平台级产品代码量分别达到30+万行和80+万行,TS 模块数均超过1000个,协同开发人员增加到20+人。由于历史原因,开发框架同时基于 React 和 Angular,考虑到产品的复杂性、人员的短缺和技术背景各异,我们尝试了各种方法打磨工具体系来提升开发效率,以下是节选的5项主要方法。

一、基于 Redux 的状态管理

从2013年React发布至今已近6个年头,前端框架逐渐形成 React/Vue/Angular 三足鼎立之势。几年前还在争论单向绑定和双向绑定孰优孰劣,现在三大框架已经不约而同选择单向绑定,双向绑定沦为单纯的语法糖。框架间的差异越来越小,加上 Ant-Design/Fusion-Design/NG-ZORRO/ElementUI 组件库的成熟,选择任一你熟悉的框架都能高效完成业务。

那接下来核心问题是什么?我们认为是 状态管理。简单应用使用组件内 State 方便快捷,但随着应用复杂度上升,会发现数据散落在不同的组件,组件通信会变得异常复杂。我们先后尝试过原生 Redux、分形 Fractal 的思路、自研类 Mobx 框架、Angular Service,最终认为 Redux 依旧是复杂应用数据流处理最佳选项之一。

庆幸的是除了 React 社区,Vue 社区有类似的 Vuex,Angular 社区有 NgRx 也提供了几乎同样的能力,甚至 NgRx 还可以无缝使用 redux-devtools 来调试状态变化。

9ccb01e70d6f79e48b9cd9e0b95852b7.png

无论如何优化,始终要遵循 Redux 三原则:

原则 方法 引发的问题 Single source of truth 组件 Stateless,数据来源于 Store 如何组织 Store? State is read-only 只能通过触发 action 来改变 State action 数量膨胀,大量样板代码 Changes are made with pure functions Reducer 是纯函数 副作用如何处理,大量样板代码 这三个问题我们是通过自研 iron-redux 库来解决,以下是背后的思考:

如何组织 Action?

  1. action type 需要全局惟一,因此我们给 action type 添加了 prefix,其实就是 namespace 的概念
  2. 为了追求体验,请求(Fetch)场景需要处理 3 种状态,对应 LOADING/SUCCESS/ERROR 这 3 个action,我们通过 FetchTypes 类型来自动生成对应到 3 个 action

如何组织 Store/Reducer?

  1. reducer 和 view 不必一一对应,应用中同时存在组件树和状态树,按照各自需要去组织,通过 connect 来绑定状态树的一个或多个分支到组件树
  2. 通过构造一些预设数据类型来减少样板代码。对于 Fetch 返回的数据我们定义了 AsyncTuple 这种类型,减少了样板代码
  3. 明确的组织结构,第1层是 ROOT,第2层是各个页面,第3层是页面内的卡片,第4层是卡片的数据,这样划分最深处基本不会超过5层

最终我们得到如下扁平的状态树。虽庞大但有序,你可以快速而明确的访问任何数据。

8d1749dc96931368230b61196c041ccf.gif

[Redux 状态树]如何减少样板代码? 使用原生 Redux,一个常见的请求处理如下。非常冗余,这是 Redux 被很多人诟病的原因。

const initialState = { loading = true, error = false, data = []};function todoApp(state = initialState, action) { switch (action.type) { case DATA_LOADING: return { ...state, loading: true, error: false } case DATA_SUCCESS: return { ...state, loading: false, data: action.payload } case DATA_ERROR: return { ...state, loading: false, error: true } default: return state }}

使用 iron-redux 后:

class InitialState { data = new AsyncTuple(true);}function reducer(state = new InitialState(), action) { switch (action.type) { /** 省略其它 action 处理 */ default: return AsyncTuple.handleAll(prefix, state, action); }}

代码量减少三分之二!!

主要做了这2点:

  1. 引入了预设的 AsyncTuple 类型,就是 {data: [], loading: boolean, error: boolean} 这样的数据结构;
  2. 使用 AsyncTuple.handleAll 处理 LOADING/SUCCESS/ERROR 这 3 种 action,handleAll 的代码很简单,使用 if 判断 action.type 的后缀即可,源码在这里。

曾经 React 和 Angular 是两个很难调和的框架,开发中浪费了我们大量的人力。通过使用轻量级的 iron-redux,完全遵循 Redux 核心原则下,我们内部 实现了除组件层以外几乎所有代码的复用。开发规范、工具库达成一致,开发人员能够无缝切换,框架差异带来的额外成本降到很低

二、全面拥抱 TypeScript

TypeScript 目前可谓大红大紫,根据 2018 stateofjs,超过 50% 的使用率以及 90% 的满意度,甚至连 Jest 也正在从 Flow 切换到 TS。如果你还没有使用,可以考虑切换,绝对能给项目带来很大提升。过去一年,我们从部分使用 TS 变为全面切换到 TS,包括我们自己开发的工具库等。

TS 最大的优势是它提供了强大的静态分析能力,结合 TSLint 能对代码做到更加严格的检查约束。传统的 EcmaScript 由于没有静态类型,即使有了 ESLint 也只能做到很基本的检查,一些 typo 问题可能线上出了 Bug 后才被发现。

下图是一个前端应用常见的4层架构。 代码和工具全面拥抱 TS 后,实现了从后端 API 接口到 View 组件的全链路静态分析,具有了完善的代码提示和校验能力。

55680903fd98687375fa8e8dd949a4bd.png

[前后端协作简图]除了上面讲的 iron-redux,我们还引入 Pont 实现前端取数,它可以自动把后端 API 映射到前端可调用的请求方法。

Pont 实现原理:(法语:桥) 是我们研发的前端取数层框架。对接的后端 API 使用 Java Swagger,Swagger 能提供所有 API 的元信息,包括请求和响应的类型格式。Pont 解析 API 元信息生成 TS 的取数函数,这些取数函数类型完美,并挂载到 API 模块下。最终代码中取数效果是这样的:

0ae4a85643a839076bab59b3c7a77a0f.png

Pont 实现的效果有:

  1. 根据方法名自动匹配 url、method,并且对应到 prams、response 类型完美,并能自动提示
  2. 后端 API 接口变更后,前端相关联的请求会自动报错,再也不担心后端悄悄改接口前端不知晓
  3. 再也不需要前后端接口约定文档,使用代码保证前端取数和后端接口定义完全一致

另外 iron-redux 能接收到 Pont 接口响应数据格式,并推导出整个 Redux 状态树的静态类型定义,Store 中的数据完美的类型提示。效果如下:

7ed8f46c05946ffcea1dbae8c6d61480.png

最终 TS 让代码更加健壮,尤其是对于大型项目,编译通过几乎就代表运行正常,也给重构增加了很多信心

三、回归 Sass/Less

2015 年我们就开始实践 CSS Modules,包括后来的 styled-components 等,到 2019 年 css-in-js 方案依旧争论不休,虽然它确实解决了一些 CSS 语言天生的问题,但同时增加了不少成本,新手不够友好、全局样式覆盖成本高涨、伪类处理复杂、与AntD等组件库结合有坑。与此同时 Sass/Less 社区也在飞速发展,尤其是 Stylelint 的成熟,可以通过技术约束的手段来避免 CSS 的 Bad Parts。

  1. 全局污染:约定每个样式文件只能有一个顶级类,如 .home-page{ .top-nav {/**/}, .main-content{ /**/ } }。如果有多个顶级类,可以使用 Stylelint rule 检测并给出警告。
  2. 依赖管理不彻底。借助 webpack 的 css-loader,已够用。
  3. JS 和 CSS 变量共享。关于 JS 和 Sass/Less 变量共享,我们摸索出了自己的解法:
// src/styles/variables.jsmodule.exports = { // 主颜色 'primary-color': '#0C4CFF', // 出错颜色 'error-color': '#F15533', // 成功颜色 'success-color': '#35B34A',};// webpack.config.jsconst styleVariables = require('src/styles/variables');// ... { test: /.scss$/, use: [ 'style-loader', 'css-loader?sourceMap&minimize', { loader: 'sass-loader', options: { data: Object.keys(styleVariables) .map(key => `$${key}: ${styleVariables[key]};`) .join(''), sourceMap: true, sourceMapContents: true } } ] }//...

在 scss 文件中,可以直接引用变量

// page.scss.button { background: $primary-color;}

四、开发工具覆盖全链路

2019 年,你几乎不可能再开发出 React/Angular/Vue 级别的框架,也没必要再造 Ant-Design/Fusion-Design/Ng-Zorro 这样的轮子。难道就没有机会了吗?

当然有,结合你自身的产品开发流程,依旧有很多机会。下面是常规项目的开发流程图,任何一个环节只要深挖,都有提升空间。如果你能通过工具减少一个或多个环节,带来的价值更大。

fd1ab11b667655cccb516fd456772cfc.png

单拿其中的【开发】环节展开,就有很多可扩展的场景:

f1d1ae08f3ca394ece6c22723c866c15.png
  1. 一个有代表性的例子是,我们开发了国际化工具 kiwi。它同样具有 TS 的类型完美,非常强大的文案提示,另外还有:VS Code 插件 kiwi linter,自动对中文文案标红,如果已有翻译文案能自动完成替换
  2. Shell 命令全量检查出没有翻译的文案,批量提交给翻译人员
  3. Codemod 脚本自动实现旧的国际化方案向 Kiwi 迁移,成本极低

除了以上三点,未来还计划开发浏览器插件来检查漏翻文案,利用 Husky 在 git 提交前对漏翻文案自动做机器翻译等等。

未来如果你只提供一个代码库,那它的价值会非常局限。你可以参照上面的图表,开发相应的扩展来丰富生态。如果你是新手,推荐学习下编译原理和对应的扩展开发规范。

五、严格彻底的 Code Review

过去的一年,我们一共进行了 1200+ 多次 Code Review(CR),很多同事从刚开始不好意思提 MR 到后来追着别人 Review,CR 成为每个人的习惯。通过 CR 让项目中任何一行代码都至少被两人触达过,减少了绝大多数的低级错误,提升了代码质量,这也是帮助新人成长最快的方式之一。

fd89e35a1cf25bc984bcc6b7f98d516f.png

【其中一个项目MR截图】Code Review 的几个技巧:

  1. No magic
  2. Explicit not implicit
  3. 覆盖度比深度重要,覆盖度追求100%
  4. 频率比仪式感重要,坐公交蹲厕所打开手机都可以 Review 别人代码,不需要专门组织会议
  5. 粒度要尽可能小,一个组件一个方法均可,可以结合 Git Flow
  6. 24h 小时内处理,无问题直接 merge,有问题一定要留 comment,并且提供 action
  7. 对于亟待上线来不及 Review 的代码,可以先合并上线,上线后再补充 Review
  8. 需要自上而下的推动,具有完善的规范,同时定期总结 Review 经验来丰富开发规范
  9. CR 并不只是为了找错,看到好的代码,不要吝啬你的赞美
  10. 本质是鼓励开发者间更多的沟通,互相学习,营造技术文化氛围

总结

以上5点当然不是我们技术的全部。除此之外我们还实践了移动端开发、可视化图表/WebGL、Web Worker、GraphQL、性能优化等等,但这些还停留在术的层面,未来到一定程度会拿出来分享。

如果你也准备或正在开发复杂的前端应用,同时团队人员多样技术背景各异,可以参考以上5点,使用 Redux 实现规范清晰可预测的状态管理,深耕 TypeScript 来提升代码健壮性和可维护性,借助各种 Lint 工具回归简单方便的 CSS,不断打磨自己的开发工具来保证开发规范高效,并严格彻底实行 Code Review 促进人的交流和提升。

作者:前端新能源

链接:https://juejin.im/post/5c617c576fb9a049e93d33a4

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

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

相关文章

Hadoop HA

HA概念: high avalability 高可用性。 hadoop 1.x非ha设计 Secondnode对元数据的可靠性有了保障,但服务的可用性不高。 即:当Namenode节点宕机了,整个hadoop就不能使用了,影响了client的使用。 hadoop 2.x的ha设计 新…

紫光展锐处理器有那些手机用_酷派将发千元5G手机,国产紫光展锐加持,主打性价比...

↑↑↑点击上方蓝字订阅每日最新热点手机资讯数年之前,“中华酷联”是国产智能手机的四大代表。不过随着越来越多的强力竞争者入局,中兴、酷派、联想渐渐衰败,仅剩华为屹立手机行业顶端。但是酷派似乎从未想过放弃,最近便要发布一…

jelly bean android,Jelly Bean占Android系统份额突破10%

Android系统份额图(腾讯科技配图)腾讯科技讯(清雨)北京时间1月4日消息,据国外媒体报道,微博)周四发布最新数据显示,Android 4.1版本和Android 4.2版本的Jelly Bean在Android系统中的份额超过了10%,另外Android 4.0版本的ICS的份额…

妲己机器人需要什么条件才能使用_estar零封YTG:平头哥快乐电竞,只有妲己没亚瑟,差评...

2020KPL秋季赛常规赛第8周最后1个比赛日的第2场比赛,结果已经尘埃落定了。而最终的比赛结果是:estarpro轻松以3比0的大比分零封战胜YTG。有一说一,这一场比赛真的是毫无悬念啊,甚至双方交手的第1小局比赛,estarpro只用…

python离线录音转文字_Python将文字转成语音并读出来的实例详解

前言 本篇文章主要介绍,如何利用Python来实现将文字转成语音。将文字转成语音主要有两种不同的实现方法:先将文字转成语音,然后再通过读取语音实现发音、直接调用系统内置的语音引擎实现发音,后一种方法的实现主要利用第三方库。 …

魅族15系统是android,魅族15系列评测:性能够用王者荣耀优化

硬件性能:中配够用,高配优秀硬件方面,文章前面的参数表已经写得很清楚,魅族15搭载的是高通骁龙660处理器,并配备4GB的运行内存;魅族15 Plus则搭载三星Exynos 8895,配备6GB运行内存。在目前的移动…

.net 怎么循环得到数组里的值_HashMap 底层实现、加载因子、容量值及死循环

写在前面:2020年面试必备的Java后端进阶面试题总结了一份复习指南在Github上,内容详细,图文并茂,有需要学习的朋友可以Star一下!GitHub地址:abel-max/Java-Study-NoteHashMap 简介HashMap 是一个基于哈希表…

hdfs命令

bin/hdfs dfs命令 appendToFile Usage: hdfs dfs -appendToFile <localsrc> ... <dst> 追加一个或者多个文件&#xff08;linux文件&#xff09; <localsrc> ...到hdfs制定文件<dst>中.也可以从命令行读取输入. hdfs dfs -appendToFile localfile /use…

eclipse jdk配置_eclipse的安装和jdk的配置(JAVA)

首先需要到eclipse官网下载(eclipse.org)点击download进入新界面点击download 64bit进入新界面 点击划线的&#xff0c;点击download也许但是比较慢&#xff0c;点击划线的会出现扩展选项&#xff0c;选择距离你比较近的节点(速度比较快)作者选的是C…

webview跟html通信的原理,1.iOS: webView与html的交互

摘要:由于最近的项目中大部分功能需要 iOS 原生端与 html 进行交互才能完美实现,所以对 iOS 与 html 的交互方式进行了学习,这篇文章主要介绍 WebViewJavascriptBridge 框架的使用.至于原生的 JavaScriptCore.framework 就不多介绍了,同时在这里推荐一个比较好的博客.http://bl…

HDFS Federation(HDFS 联盟)介绍

1. 当前HDFS架构和功能概述 我们先回顾一下HDFS功能。HDFS实际上具有两个功能&#xff1a;命名空间管理&#xff08;Namespace management&#xff09;和块/存储管理服务&#xff08;block/storage management&#xff09;。 1.1 命名空间管理 HDFS的命名空间包含目录、文件和块…

linux java 部署 生产环境

2019独角兽企业重金招聘Python工程师标准>>> 下载文件 首先进入网页&#xff1a; http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 点击Accept License Agreement后选择jdk-8u161-linux-x64.tar.gz&#xff0c;下载。 配置环…

华为鸿蒙发布作文,华为鸿蒙OS定档6月2日发布!MatePad Pro 2或同台亮相:首发预装...

5月25日一早&#xff0c;原华为EMUI官微就正式宣布更名为Harmony OS&#xff0c;并宣布将在6月2日晚20点召开鸿蒙操作系统及华为全场景新品发布会&#xff0c;届时将正式发布鸿蒙OS正式版。据近期进行开发者测试的用户反馈&#xff0c;鸿蒙OS目前已经非常完善&#xff0c;且稳定…

python如何根据数据画散点图_如何用python画出样本的散点图?

用python画样本散点图的方法&#xff1a; 数据&#xff08;取第一列作为x&#xff0c;取第四列作为y&#xff09;如下&#xff1a;实现代码如下&#xff1a;import matplotlib.pyplot as plt import numpy as np # 定义画散点图的函数 def draw_scatter(n, s): ""&qu…

Hadoop RPC框架

原文&#xff1a;http://blog.csdn.net/thomas0yang/article/details/41211259 ---------------------------------------------------------------------------------------------- 1、RPC框架概述1.1 RPC&#xff08;Remote Procedure Call Protocol&#xff09;——远程过程…

centos7 校正linux系统时间_Linux系统:Centos7下搭建ClickHouse列式存储数据库

一、ClickHouse简介1、基础简介Yandex开源的数据分析的数据库&#xff0c;名字叫做ClickHouse&#xff0c;适合流式或批次入库的时序数据。ClickHouse不应该被用作通用数据库&#xff0c;而是作为超高性能的海量数据快速查询的分布式实时处理平台&#xff0c;在数据汇总查询方面…

html调用js页面显示不出来了,JS代码文件调用显示乱码,直接写在html页面的里可以调用,但是单独放在js文件里不能调用...

最近遇到了一个很奇怪的问题&#xff0c;就是在HTML网页代码里直接写JS代码可以正常运行的代码&#xff0c;使用JS文件调用就不行。var cities [ {"name" : "北京"}, {"name" : "上海"}, {"name" : "广州"} ];$(…

水系图一般在哪里找得到_城市供水系统防护体系的探索与思考

城市是一个国家或地区的政治、经济和文化中心&#xff0c; 在战争中常常被选为重点打击目标。1988年&#xff0c;时任美国空军司令部副参谋长助理的约翰A. 沃登上校提出“五环”目标打击理论&#xff0c;将 对敌打击目标分为五个层&#xff0c;其中就将基础设施列为第三层打击目…

CES 2017前瞻之AI:无人机依旧小巧,机器人主打家庭服务

再过2天&#xff0c;CES 2017就要开始了&#xff0c;根据这些已知晓的部分展商&#xff0c;我们也许能够看到未来的一些趋势。 还有2天&#xff0c;备受瞩目的CES 2017&#xff08;2017年国际消费类电子产品展览会&#xff09;就要拉开帷幕了。 每一年&#xff0c;CES上都会出…

ionic html5 上传图片,ionic4+angular7+cordova上传图片功能的实例代码

前言ionic是一个垮平台开发框架&#xff0c;可通过web技术开发出多平台的应用。但只建议开发简单应用。复杂的应用需要用到许多cordova插件&#xff0c;而cordova插件的更新或者移动平台的更新很可能导致插件的不可用&#xff0c;维护升级成本较高。安装插件安装插件Image Pick…