架构

组件式构建项目

大型项目的最坏的隐患就是维护一个庞大的,含有几百个依赖的代码库 - 当开发人员准备整合新的需求的时候,这样一个庞然大物势必减缓了开发效率。反之,把您的代码拆分成组件,每一个组件有它自己的文件夹和代码库,并且确保每一个组件小而简单。查看正确的项目结构的例子请访问下面的 ‘更多’ 链接。
否则: 当编写新需求的开发人员逐步意识到他所做改变的影响,并担心会破坏其他的依赖模块 - 部署会变得更慢,风险更大。当所有业务逻辑没有被分开,这也会被认为很难扩展

例如使用Lerna

封装公共模块成为NPM的包

TL;DR: 由大量代码构成的一个大型应用中,贯彻全局的,比如日志,加密和其它类似的公共组件,应该进行封装,并暴露成一个私有的NPM包。这将使其在更多的代码库和项目中被使用变成了可能。
否则: 您将不得不重造部署和依赖的轮子。

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

错误处理最佳实践

仅使用内建的错误对象,reject一个promise,抛出异常或发出(emit)错误 - 使用内建的错误对象将会增加设计一致性,并防止信息的丢失。

  • 正例 ```javascript //从典型函数抛出错误, 无论是同步还是异步 if(!productToAdd) throw new Error(“How can I add new product when no value provided?”);

//从EventEmitter抛出错误 const myEmitter = new MyEmitter(); myEmitter.emit(‘error’, new Error(‘whoops!’));

//从promise抛出错误 return new promise(function (resolve, reject) { Return DAL.getProduct(productToAdd.id).then((existingProduct) => { if(existingProduct != null) reject(new Error(“Why fooling us and trying to add an existing product?”));

  1. - 反例
  2. ```javascript
  3. //抛出字符串错误缺少任何stack trace信息和其他重要属性
  4. if(!productToAdd)
  5. throw ("How can I add new product when no value provided?");

代码规范

避免使用匿名函数

命名所有方法,包含闭包和回调,避免匿名汉法。否则使用一个内存快照调试线上问题,非常困难。因为严重的内存泄漏问题很可能是匿名方法里面产生的。

尽量使用箭头函数

保持上下文this的一致

测试和总体的质量实践

锁住依赖

关键的依赖库要锁住,避免测试环境和线上的依赖不同导致错误。

使用非root用户运行Nodejs

避免带来安全隐患、和权限操作问题。

使用子进程的时候要格外小心

尽可能避免使用子进程childProcess,如果必须这样做,必须验证和清理以减轻shell注入攻击。
childProcess.execFile可以执行单个命令,可以对命令做白名单处理。

参考链接