10个技巧,让你在 2017 年成为更好的Node开发者

简介:

在2012年,我加入了Storify并开始使用Node作为我的主要语言。从那以后,我从未回首过去并觉得我错过了Python,Ruby,Java以及PHP,这些在过去10年里,我在web开发过程中使用的语言。下面我将列出10条建议,这些建议可以帮助你在2017年成为一个更好的Node开发者。其中一些建议是我在日常实践中所学到的,另一些是从那些写了最流行的Node和npm模块的人们身上学到的。 下面是我们将要介绍的内容:

本文是由我们的客座作者Azat Mardan写的。SitePoint引入客座帖子的目的是希望能给你带来web社区里著名作者和演讲者的有趣内容。

在2012年,我加入了Storify并开始使用Node作为我的主要语言。从那以后,我从未回首过去并觉得我错过了Python,Ruby,Java以及PHP,这些在过去10年里,我在web开发过程中使用的语言。

Storify提供给我一个很有趣的工作,因为Storify和其他的公司不太一样,Storify之前(可能到现在也是)所有的代码都是由JavaScript编写的。而大多数公司,特别是大公司,例如PayPal,Walmart(沃尔玛)或者Capital One(第一资本),只是在某一些特定的部分使用了Node。通常,他们使用Node作为API接口或者用在业务流程层,这样做是很好的。但是作为一个软件工程师,没什么比得上能够完全沉浸在Node环境里。

下面我将列出10条建议,这些建议可以帮助你在2017年成为一个更好的Node开发者。其中一些建议是我在日常实践中所学到的,另一些是从那些写了最流行的Node和npm模块的人们身上学到的。 下面是我们将要介绍的内容:

  1. 避免复杂性 — 尽可能将你的代码块拆到最小,要小到极致。

  2. 使用异步编程 — 像躲避瘟疫般避免使用同步代码。

  3. 避免require阻塞 — 把你所有的require声明都放在文件的顶部,因为require是同步的,会阻塞代码运行。

  4. 了解require缓存 — 了解它则可以利用它,否则它可能会带来bug。

  5. 始终检查错误 — 错误不是足球,任何时候都不要抛出错误或者跳过错误检查。

  6. 只在同步代码中使用try…catch — 在异步代码中try...catch是没有作用的。V8引擎针对try...catch无法进行优化。

  7. 返回callbacks或者使用if … else — 返回一个callback只是为了确保不继续执行。

  8. 监听错误事件 — 几乎所有的Node的类/对象都有event emitter(观察者模式)并且会广播error事件,确保你监听了它们。

  9. 了解你的npm — 使用-S或者-D来安装模块来代替--save或者--save-dev`。

  10. 在package.json中使用精确的版本号: npm在使用-S来安装模块时会自动使用默认的版本号,你需要手动修改去锁定版本号。除非是开源模块,否者不要相信你的项目中的SemVer(语义化版本标准)。

  11. 加分 — 使用不同的依赖。把项目在开发阶段需要的东西放在 devDependencies 中,记得使用 npm i --production。多余的依赖越多,出现问题的风险就越大。

好的,接下来让我们一个个单独地去了解上面的每一点。

避免复杂性

让我看一眼npm的创造者Isaac Z. Schlueter写的一些模块,例如,use-strict,这个模块是用来在Javascript中强制使用严格模式,这个模块仅仅只有三行代码:

微信截图_20170206141432.png

所以我们为什么要避免复杂性呢? 一个起源于美国海军的著名短语:KEEP IT SIMPLE STUPID(或者是“Keep it simple, stupid”)。这就是原因。事实说明,人类大脑在任何一个时间只能在其工作记忆中保持五到七个项目。

把你的代码模块化成一个更加小的部分,你和其他的开发者会更加好的理解它。你也可以更加好的去测试它。如下例子,

或者是

我相信大多数人都会喜欢第二个例子,特别是光看名字就能了解其作用。当日,在你编写代码的时候,你可能认为你知道代码是如何运行的。甚至你想要展示你把几个功能连接在一起写在同一行中是多么的机智。但是,这样你是写了一段愚蠢的代码。如果你思考的很复杂去写这代码,那么今后你再去看这段代码将会很难去理解。保证你的代码简单,特别是在Node的异步代码中。

当然也会有left-pad 事件,但是其实它只是影响了依赖于left-pad模块的项目而且11分钟后就发布了替代品。代码的最小化带来的好处超过了它的缺点。npm已经改变了发布策略,任何重要的项目都应该使用缓存或私有的源(作为临时解决方案)。

使用异步编程

在Node中同步代码只要很小的一部分。这些代码大多数都是用于命令行工具或者其他与web应用无关的脚本。Node开发者大多数都是编写web应用,因此使用异步代码可以避免阻塞现场。

例如,当你在编写一个数据库的脚本或者是一个不需要控制并行的任务时,下面这种写法可能是可以的:

但是当你创建一个web应用时,下面这个写法会更好:

这个区别在于你是否需要编写一个并发(通常是长期运行)或者非并发(短期运行)的系统。根据经验来说,总是要在Node中使用异步代码。

避免require阻塞

Node有一个使用了CommonJS模块格式的简单的模块加载系统。它是基于require函数,require函数可以很方便的在不同的文件中引入模块。和AMD/requirejs不同,Node/CommonJS的模块加载时同步的。require的工作方式是:引入一个模块或者一个文件export的内容:

微信截图_20170206141653.png

但是大多数的开发者并不知道require是会被缓存的。因此,只要解析的文件名(resolved filename)没有剧烈的变化(比如npm模块不存在的情况),模块的代码只会被执行并存入变量中一次(在当前进程中)。这是一个很好的优化。当然,即使有了缓存,你最好还是把你的require声明写在开头。下面这段代码,它在路由中真正使用到了axios模块的时候才加载。当请求发送的时候/connect会因为需要加载模块所以会变得慢。

一个更好,性能更优的方式是在服务定义之前就引入模块而不是在路由中:

知道require会被缓存

我在上面一节已经提到了require会被缓存,但是有趣的是我们在module.exports之外也会有代码。举例来说:

从中我们了解到有一些代码只会运行一次,你可以使用这个特性来优化你的代码。

始终检查错误

Node不是Java。在Java中,你可以抛出错误,因为如果发生了错误那么你会希望应用不在继续执行。在Java中,你可以在外层仅仅使用一个简单的try...catch就可以处理多个错误。

但是在Node中并不是这样的。自从Node使用了事件循环和异步执行后,任何的错误发生时都会与错误处理器(例如try...catch)的上下文分离,下面这样做在Node中是没有用的:

但是try...catch在同步代码中是可以被用的。前面的代码片段可以被更好的重构为:

如果我们无法将request的返回内容包裹在try...catch中,那么我们将没有办法去处理请求的错误。Node的开发者通过在返回的参数里面加上error来解决了这个问题。因此,我们需要在每一个回调中手动去处理错误。你可以去检查这些错误(判断error不是null),然后展示错误信息给用户或者展示在客户端上并且记录它, 或者你可以通过调用 callback ,给它传 error 参数,将错误传回给上一级调用栈(如果你在调用栈之上有另一个回调函数)。

一个小技巧是你可以使用okay库。你可以像下面的例子一样使用它去避免在回调地狱中手动去检查错误(你好, 回调地狱).

返回回调或者使用if … else

Node是并行的。但是如果你不够细心也会因为这个特性产生bug。 为了安全起见,应该要使用return来终止代码的继续执行:

这样可以避免一些因为代码逻辑的处理不当导致一些不应该执行的内容(或者错误)被执行。

请确保使用return去阻止代码的继续执行。

监听 error 事件

Node中几乎所有的类/对象都有事件分发器(观察者模式)并且会广播 error 事件。 这是一个很好的特性,可以使开发者在这些讨厌的错误造成巨大后果之前捕捉到它们。

养成一个通过.on()来创建error事件监听的好习惯:

了解你的npm

很多的Node和前端的开发者知道在安装模块的时候使用--save会在安装模块的同时,会在package.json保存一条含有模块版本信息的条目。当然,还有--save-dev可以用于安装devDependencies(在生成环境中不需要的模块)。但是你知道用-S和-D是否可以代替--save 和--save-dev么?答案是可以的。

当你安装模块的时候,你需要删除-S和-D自动为你模块的版本号添加的^标签。否者当你使用npm install(或者npm i)安装模块的时候,就会自动拉取最新的镜像(版本号的第二位数字)。例如v6.1.0就是v6.2.0的一个镜像分支。

npm团队推荐使用semver,但是你最好不要这样。npm团队认为开源开发者会遵守semver所以他们在npm安装时自动加上了^。没有人可以去保证,所以最好是锁定你的版本号。更好的办法是使用shrinkwrap:npm shrinkwrap会生成一个包含依赖的具体版本的文件。


作者:wleonardo 译

来源:51CTO

相关文章
|
SQL JavaScript 开发者
Node.js:insert-sql帮助开发者生成SQL插入语句
Node.js:insert-sql帮助开发者生成SQL插入语句
158 0
|
开发框架 运维 JavaScript
Node.js 2021年开发者报告解读:健康稳步的发展中
Node.js 2021年开发者报告解读:健康稳步的发展中
317 0
Node.js 2021年开发者报告解读:健康稳步的发展中
|
存储 缓存 前端开发
技术实践第一期|友盟+开发者平台Node.js重构之路
因原有SDK版本升级配置文件较复杂,需要在java端通过多个文件查询整合得到前端界面勾选内容数据,且升级SDK均需要手动拉取oss文件到服务端本地缓存,导致维护成本较高,且时间悠久无相关产品及开发文档说明,因此在本次业务升级中重构改应用。
技术实践第一期|友盟+开发者平台Node.js重构之路
|
JavaScript 前端开发 Linux
为 Node.js 开发者准备的 8 本免费在线电子书
Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始。比较独特的是,Node.js会假设你是在POSIX环境下运行它Linux 或 Mac OS X。如果你是在Windows下,那就需要安装MinGW以获得一个仿POSIX的环境。在Node中,Http是首要的。Node为创建http服务器作了优化,所以你在网上看到的大部分示例和库都是集中在web上(http框架、模板库等)。
406 0
为 Node.js 开发者准备的 8 本免费在线电子书
|
JavaScript Java 程序员
[Coke,浏览器,JS,Node,js]Node.js开发者必须了解的4个JS要点
  1. 非阻塞(Non-blocking)或异步I/O   由于Node.js一个服务器端框架,所以它主要工作之一是处理浏览器请求。在传统的I/O系统中,每个请求的发出都是在上一请求到达之后才发出的。所以这被称为阻塞(blocking)I/O。服务器会阻挡其它的请求以处理当前请求,从而导致浏览器等待。
157 0
|
JavaScript 前端开发 Serverless
2021 Node.js 开发者问卷调查
BFF、SSR、Serverless…… 随着技术的浪潮不断翻涌, Node.js 正在为我们逐渐带来更多的生产力。为了更好的了解 Node.js 生态现状,帮助大家: - 了解大家都是如何使用 Node.js? - 梳理这个语言的技术栈 - 聚焦大家都在关注些什么? - 帮助开发者找准这个语言的定位(用来干什么的) - 找到目前生态所缺乏的以及被期望的内容 - 辅助企业招聘 欢迎您来参加 N
214 0
|
消息中间件 JavaScript 前端开发
2020 年 Node.js 开发者调查报告
本次调查由阿里巴巴、腾讯等公司领衔,调查时间从 2020 年 2 月至 4 月,以中文进行。截止至 4 月 10 日共有 1113 名受访者参加调研。本报告将从 Nodejs 开发者人群、应用场景、开发场景等多个维度分析当下 Nodejs 开发生态的现状。
2020 年 Node.js 开发者调查报告
|
JavaScript Serverless 开发者
Node.js 开发者调研
BFF、SSR、Serverless…… 随着技术的浪潮不断翻涌, Node.js 正在为我们逐渐带来更多的生产力。而阿里巴巴作为国内大规模使用 Node.js 的集团,毫无疑问是国内生态中重要的一部分,为了更好的了解 Node.js 生态现状,帮助集团内外: - 了解大家都是如何使用 Node.js? - 梳理这个语言的技术栈 - 大家都在关注些什么? - 帮助开发者找准这个语言的定
448 0