熟悉 Node 或前端 JavaScript 工作的同学都知道,社区中的可用模块有数十万之多。
开发人员经常会提问或抱怨,比如说:
“开发易,选模块难…”
“X 模块和 Y 模块区别在哪里,哪一个更好?”
“npm 很好用,可是那些模块指不定半年一年多就没用了,具体看它们的支持情况。”
在谈到这些问题时,你通常会得到十个不同的答案。每个人都会向你推荐他最宝贝的模块,然后大家就会为哪个模块是最好的这个话题吵得不可开交。
选择 npm 模块时容易遇到“分析瘫痪”这种情况。可选项实在太多了,还总有一大堆新模块被吹成是“你,值得拥有”,想要为自己的项目选出合适的模块实在不是件容易的事情。而且许多模块做的事情都是差不多(或者完全一样)的,更给人添乱。
其实你用不着浪费时间在谷歌或 npmjs.org 上乱搜一通,影响你的应用构建工作;你要做的就是知道在什么时候选择哪些模块。
精选列表
为了帮你解决这个问题,本文针对各种最常见的问题类型制作了一份模块列表(例如 Web 框架、模板、身份验证等),并告诉你这些模块应该何时使用。
有一些注意事项:有些模块你可能已经很熟悉了,但有时你会遇到完全陌生的技术栈(比如说身份验证或 Web Socket 之类),这时候你需要知道用哪些模块可以完成工作。你可能觉得某款模块更出色。也可能你的用例/需求不在下面的列表里。我并没有在每个分类下塞一堆选项,而是尽量精简,避免陷入分析瘫痪的陷阱。如果你的场景比较特殊,那么就得自己做些调查来做补充了;这个列表的目的是让你更快地投身工作。
这些模块是基于下面的原则挑选出来的:
它们完成工作的能力如何。
社区规模(对支持/故障排除很重要)。
积极维护
如果你还是觉得信息不足,难下决定,我建议使用 slant.co 和 nodejs.libhunt.com 来做比较。npmtrends.com 这个网站可以对比不同包的下载量/问题数/GitHub 星数,也很有用(感谢 Bill 推荐)。
注意:为了控制范围,记住这些模块都是服务端的。很多模块既能在客户端也能在服务端使用,但总的来说是“服务端优先”原则。
HTTP 请求
Request:
需要发起基于回调的 HTTP 请求时使用,例如从一个 REST 服务到另一个 REST 服务。
Axios:
需要发起基于 Promise 的 HTTP 请求时使用。
注意:可以使用 request-promise,但 axios 的依赖项更少,而且是基于原生 Promise 的。
Web 框架
Express:
你的 API、网站或单页应用需要一个轻量级 Web 框架时用它。
你不介意使用开箱即用的回调来实现异步。
你希望有一个搭配框架使用的丰富的模块生态系统。
你希望框架有一个大型社区来提供支持并排除故障。
Koa:
你想要比 Express 还轻量的框架时就选它。
Koa 更像是一个中间件层,不提供开箱即用的模板或路由,更适合 API 开发。
你想要开箱即用的 async/await 支持。
Hapi:
你想要一个比 Express 或 Koa 有更多“部件”的框架时选它,但它集成的东西没 Sails 那么多。
Sails:
你想要像 Rails 之类的东西时就用它,它集成了一大堆东西(但其中有很多可能是你用不着的)。
验证
Ajv:
在需要验证 JSON 时使用(例如来自一个 Web 请求的 JSON)。
你想与应用程序的非 JS 部分共享这些 schema(它是 JSON,所以你可以这样做)。
Joi:
你需要验证输入并且喜欢它下面这种样式时就用它
它不是在 JSON 中定义 schema
你正在使用 Hapi(Joi 自带它,开箱即用)
身份验证
Passport:
需要为你的网站或 API 使用身份验证中间件时用它。
你希望能选择多种身份验证类型(Oauth,Facebook 等)。
你需要管理会话。
异步
Async(库):
你需要使用只支持回调,不支持 Promise 的旧版 Node 时选它
ES6 原生 Promise(原生 JS,不是 npm):
使用 Node 0.12 以上版本时用它。
还要考虑你的团队是否熟悉 Promise。现在大多数开发者应该都很熟悉了。
async/await(原生 JS,不是 npm):
你好容易逃离了回调地狱,结果又掉进 Promise 地狱的时候用它。
你有很多来自 Promise 的.then 和.catch
数据库:
下面列出了数据库驱动程序、ORM 和查询构建器等内容。先别急着找 ORM,我强烈建议你先确认自己的确用得着 ORM 再说。很多时候用原始的 SQL 或查询构建器就够了,而 ORM 会加入另一层抽象,性价比不够高。
mysql、node-postgres:
在不需要完整的 ORM 时使用,它们使用原始的 SQL 查询数据库(这些是驱动程序)
node-mongodb-native:
在不需要完整的 ORM 时使用,它会直接查询 MongoDB
Mongoose:
你更想在 MongoDB 上使用 ORM 时用它
Knex:
你不需要完整的 ORM 解决方案,只是想在写查询代码时方便一些就用它。
Knex 是一个生成 SQL 的查询构建器。
你有一个 Postgres、MSSQL、MySQL、MariaDB、SQLite3、Oracle 或 Amazon Redshift 数据库。
Objection.js:
你想要一个支持 Knex 所有功能的 ORM,不用查询 DSL(所以你写的代码更接近原始 SQL),还有一个基于 Promise 的 API 和详尽的文档。
进程管理
想要对比进程管理器的话,可以参考http://strong-pm.io/compare/。注意:它们还会同时对比 StrongLoop 进程管理器,后者挺好用但是有些复杂。我建议你先找找解决方案,然后再决定是否使用 StrongLoop。
PM2:
你需要一个能够在服务崩溃时重新启动服务,并能用来控制集群的进程管理器时选它。
注意:据说 PM2 可能违反 AGPL 许可证,相关讨论可以看这里。我认为它用起来没什么问题。但如果你有问题/疑虑就请咨询你的法律部门,因为我不是律师。
forever:
你想要一个能在服务崩溃时重启服务的进程管理器时可以选它。
你的部署比较小(支持集群的 pm2 适用于更大规模的部署)。如果你只有少量服务/进程,那么用 forever 就很合适。
nodemon:
你想监视应用程序中的任何代码更改,并在本地开发时自动重启服务器时用它。
它非常适合开发工作!
Web Socket:
Web Socket 这里我单推 primus。它支持所有流行的 Web Socket 实现,而且更新维护很勤快;如果你想换个库用,那么改一行代码就能轻松切换不同的库了。
Primus:
你需要 Web Socket,但又不想局限在某个特定的 Web Socket 实现时用它。
API 文档
Swagger-node:
你需要为 REST API 编写文档,并需要针对端点测试请求时用它。
实用程序/杂项:
Lodash:
在需要 JS 实用程序库时使用。
你使用了大量的 OOP。
Ramda:
你想用更加函数式的风格编程,用函数组合写代码时用它。
你想在函数式编程中使用 lodash 一类的东西。
Moment:
在需要解析、验证、操作和显示日期/时间时使用。
UUID:
需要很难破解的随机、独特的 id 时用它。
NVM:
你希望能在环境中安装的多个版本 Node 之间切换时用它。
FS-EXTRA:
你需要递归 mkdir、rm -rf 和 Node 中缺少的其他文件系统实用程序时用它。
Nodemailer:
需要从 Node 中发送电子邮件时使用。
Dotenv:
需要将.env 文件中的环境变量加载到 process.env 时使用。
CLI
Commander:
你要构建一个 CLI 实用程序,将所有参数作为命令行上的标志时就用它。
Inquirer:
你想要构建一个按顺序确定选项的“交互式”CLI 实用程序时用它(类似运行 npm init 时的方法,它会问你一系列问题来生成 package.json 文件)。
日志
Winston:
在需要日志库和不同的日志输出时使用。
Bunyan:
在需要日志库时使用,并且可以处理 JSON 是唯一的日志输出的情况。
你想为不同的组件、请求或功能使用不同的日志记录器(比如说这些记录器可能以不同的方式解析)。
Morgan:
在使用 Express 并且想要记录 HTTP 请求时使用。
注意:它是和类似 Winston 或 Bunyan 的工具并用的。由于它是中间件,所以知道如何处理请求并记录它,但不会像 Winston 和 Bunyan 那样负责传输到日志输出中。
模板
Pug(原 Jade):
你需要一个易读的服务端模板引擎并附带开箱即用的子布局块支持时就用它。
你的输出只有 HTML。
EJS:
你需要一个完全使用 JS 的服务端模板引擎并且可以容忍空格缩进时选它(Pug 没有缩进)
。
注意:它不支持异步 JS 函数。
测试
Mocha:
在需要编写和运行单元测试时使用。
Chai:
你的单元测试需要一个断言库时用它。
注意:它和 Mocha 是搭配使用的。
Chai-as-promised:
你需要针对 promise 的断言库,但不想用 then 或 catch 时用它。
Sinon:
需要一个 mocking 库进行测试时使用。
工具
ESdoc:
你在使用较新版本的 JS,想从代码中生成 API 文档时用它。
支持当前版本的 JS,默认目标 class。所以如果你在代码中使用原型,请使用 JSdoc。
JSdoc:
你需要支持 ES6 的代码 API 文档生成器时用它。
支持类和原型。
ESlint:
你需要一个 linter 来自动查找(和修复)代码中的语法和模式问题时选它。
调试
目前 Node 的原生调试已经够用了,我建议用原生功能就行。几年前一些额外的 npm 模块还能有些帮助,有的特定场景可能用得着;但是现在有了足够的原生支持,如果你没什么疯狂的调试需求就最好省掉额外的依赖项。
小结
挑选模块可能会很费事,但用些技巧就能事半功倍。如果你犯了选择困难症,甚至不知道从哪里下手的话就看看本文的推荐吧。
英文原文:https://www.coreycleary.me/which-of-the-635000-npm-modules-do-i-choose/
评论