Node最佳实践学习

前言

18年攒了不少资料没看,年初趁有空一个个解决掉。 一个接近2万5颗星星的库Node Best Practices

将结合去年的一些工作经验谈一下自己的理解。

正文

组件式构建你的解决方案

大型项目的最坏的隐患就是维护一个庞大的,含有几百个依赖的代码库 - 当开发人员准备整合新的需求的时候,这样一个庞然大物势必减缓了开发效率。反之,把您的代码拆分成组件,每一个组件有它自己的文件夹和代码库,并且确保每一个组件小而简单。

解读

组件式开发已经成为前端的一个必备技能,而且现在各个框架的设计都是为了更好的拆分与组合。

接触过几种类型

1、每个组件有自己的数据源,将业务逻辑和组件界面分开,通过一个Index文件将其组合并暴露出去。

优势是清清爽爽,劣势是每增一个组件就要新建好几个文件。这之前有想过通过写一个通用模板生成的辅助工具来帮助创建。

2、每个组件依赖同一个数据源,公用组件抽离,只注入参数使用,业务组件之间引用。

这个优势是将业务组件和公用组件分开了,而且逻辑全在业务组件内。复用性提升,而且一些项目会将布局也抽象成公用组件。
劣势是抽象需要时间,会比直接写需要考虑更多。
但是侧面也是在提升自身能力。

分层设计组件,保持Express在特定的区域

每一个组件都应该包含’层级’ - 一个专注的用于接入网络,逻辑,数据的概念。这样不仅获得一个清晰的分离考量,而且使仿真和测试系统变得异常容易。尽管这是一个普通的模式,但接口开发者易于混淆层级关系,比如把网络层的对象(Express req, res)传给业务逻辑和数据层 - 这会令您的应用彼此依赖。

解读

这个不仅实用expre,koa也同样适用。主要就是node这块如果需要处理比较复杂的情况(比如登录校验),以及做接口转发等。需要明确把中间层划分,路由划分(页面路由与接口路由),业务处理划分。

最主要的就是要保证node这块模块划分清晰。

封装公共模块成为NPM的包

由大量代码构成的一个大型应用中,贯彻全局的,比如日志,加密和其它类似的公共组件,应该进行封装,并暴露成一个私有的NPM包。这将使其在更多的代码库和项目中被使用变成了可能

解读

这个很重要,是公共组件再往上层的一种抽象,但是工作那么久还没去做过类似,更多的是公共组件的开发。今年将重点去研究并使用,提高公共模块的复用率。

使用易于设置环境变量,安全和分级的配置

一个完美无瑕的配置安装应该确保 (a) 元素可以从文件中,也可以从环境变量中读取 (b) 密码排除在提交的代码之外 (c) 为了易于检索,配置是分级的。仅有几个包可以满足这样的条件,比如rc, nconf 和 config。

解读

这个在工作是切实体会到了配置的重要性,它可以帮助在开发的时候减少不少工作量,而且如果配置文件搞定了,根据环境变量去读取配置,那么在部署阶段就不需要去更改一些内容了。一次配置,整个应用生命周期都可以使用。

错误处理最佳实践

使用 Async-Await 和 promises 用于异步错误处理

很多人抛出异常使用字符串类型或一些自定义类型 - 这会导致错误处理逻辑和模块间的调用复杂化。是否您reject一个promise,抛出异常或发出(emit)错误 - 使用内建的错误对象将会增加设计一致性,并防止信息的丢失.

运行错误(例如, API接受到一个无效的输入)指的是一些已知场景下的错误,这类错误的影响已经完全被理解,并能被考虑周全的处理掉。同时,程序设计错误(例如,尝试读取未定义的变量)指的是未知的编码问题,影响到应用得当的重启。

错误处理逻辑,比如给管理员发送邮件,日志应该封装在一个特定的,集中的对象当中,这样当错误产生的时候,所有的终端(例如 Express中间件,cron任务,单元测试)都可以调用。

解读

错误处理,用到的其实很常见就是异步自己处理一个中间件,对successerror分别处理。然后抛出异常也要打印下全局日志。

编码风格实践

使用ESLint

在同一行开始一个代码块的大括号

不要忘记分号

命名您的方法,命名所有的方法,包含闭包和回调, 避免匿名方法。当剖析一个node应用的时候,这是特别有用的。命名所有的方法将会使您非常容易的理解内存快照中您正在查看的内容

解读

一些语法的风格其实可以用vscode的插件帮助一键格式化。但是函数方法这些命名规范都得按照团队的开发约定来。一般会吸取大公司的经验,比如Airbnb的javascript规范。

测试和总体的质量实践

至少,编写API(组件)测试

解读

测试这块一直是前端开发硬伤,有时候是项目紧,有时候是不知从何入手,而且不是每个项目都有必要写前端测试,因此这块一直属于空白。但是开发了不少项目下来,发现还是能做一些事情,来帮助提升代码质量。

比如如果是node层,可以考虑做接口的api单元测试。这个函数式的单元测试会比较容易写,而且在提测部署前跑一下测试,应该还是能发现一些问题的。

上线实践

监控

使用智能日志增加透明度,日志可以是调试语句的一个不能说话的仓库,或者表述应用运行过程的一个漂亮仪表板的驱动。从第1天计划您的日志平台:如何收集、存储和分析日志,以确保所需信息(例如,错误率、通过服务和服务器等完成整个事务)都能被提取出来。

锁住依赖. 您的代码必须在所有的环境中是相同的,但是令人惊讶的是,NPM默认情况下会让依赖在不同环境下发生偏移 – 当在不同的环境中安装包的时候,它试图拿包的最新版本。克服这种问题可以利用NPM配置文件, .npmrc,告诉每个环境保存准确的(不是最新的)包的版本。另外,对于更精细的控制,使用NPM “shrinkwrap”。*更新:作为NPM5,依赖默认锁定。新的包管理工具,Yarn,也默认锁定。

设置NODE_ENV=production.设置环境变量NODE_ENV为‘production’ 或者 ‘development’,这是一个是否激活上线优化的标志 - 很多NPM的包通过它来判断当前的环境,据此优化生产环境代码。

解读

这上面列的每一条都在真实环境中遇到过问题。尤其是版本需要锁死,不然很容易造成开发环境和上线环境的差异,然后排查bug费时。

日志这块基本就是在Node端把每个请求的header,请求时间,各种参数,返回信息都打印出来。

Table of Contents