2012年,我加入了Storify并开始使用Node作为我的主要语言。从那时起,我再也没有回过头来感??觉自己错过了Python、Ruby、Java和PHP,这些是我过去10年在Web开发中使用的语言。下面我将列出10个技巧,它们将帮助您在2017年成为更好的Node开发人员。这些建议中的一些是我在日常实践中学到的,还有一些是我从编写最流行的Node和npm模块。以下是我们将介绍的内容:本文由我们的客座作者AzatMardan撰写。SitePoint引入访客帖子,希望为您带来网络社区中知名作者和演讲者的有趣内容。2012年,我加入了Storify,开始使用Node作为我的主要语言。从那时起,我再也没有回过头来感??觉自己错过了Python、Ruby、Java和PHP,这些是我过去10年在Web开发中使用的语言。Storify为我提供了一份非常有趣的工作,因为Storify与其他公司不同,Storify之前(可能仍然是)所有代码都是用JavaScript编写的。而大多数公司,尤其是大公司,如PayPal、沃尔玛(Walmart)或第一资本(FirstCapital),只在某些特定的部分使用Node。通常,他们使用Node作为API接口或在编排层,这很好。但作为一名软件工程师,没有什么比完全沉浸在Node环境中更好的了。下面我将列出10个技巧,它们将帮助您在2017年成为更好的Node开发人员。这些建议中的一些是我在日常实践中学到的,还有一些是我从编写最流行的Node和npm模块。以下是我们要介绍的内容:避免复杂性——将您的代码块分解为尽可能小的尺寸。尽可能小。使用异步编程——避免像瘟疫一样的同步代码。避免require阻塞-将所有require语句放在文件的顶部,因为require是同步的并且会阻塞代码执行。知道require缓存-知道它,你就可以利用它,否则它会引入错误。始终检查错误-错误不是足球,任何时候都不要抛出错误或跳过错误检查。仅在同步代码中使用try...catch—try...catch在异步代码中无效。V8引擎无法针对try...catch进行优化。返回回调或使用if...else—返回回调只是为了确保不会继续执行。监听错误事件——几乎所有的Node类/对象都有事件发射器(观察者模式)和广播错误事件,确保你监听它们。了解你的npm——使用-S或-D代替--save或--save-dev来安装模块。在package.json中使用精确版本号:npm在使用-S安装模块时会自动使用默认版本号,需要手动修改锁定版本号。除非它是一个开源模块,否则不要在你的项目中信任SemVer(语义版本控制标准)。奖励积分-使用不同的依赖项。把项目在开发阶段需要的东西放到devDependencies里面,记得用npmi--production。冗余依赖项越多,出现问题的风险就越大。好的,让我们逐一分析以上各点。避免复杂性让我看一下npm创建者IsaacZ.Schlueter写的一些模块,例如use-strict,这个模块是用来在Javascript中强制执行严格模式的,这个模块只有三行代码:所以我们为什么要避免复杂?一个著名的短语起源于美国海军:KEEPITSIMPLESTUPID(或“保持简单,愚蠢”)。这就是为什么。事实证明,人脑在任何时候的工作记忆中只能保存五到七个项目。通过将您的代码模块化成更小的部分,您和其他开发人员将更好地理解它。你也可以更好地测试它。下面这个例子,或者相信大多数人都会喜欢第二个例子,尤其是光看名字就能明白它的作用。回到今天,当您编写代码时,您可能认为您知道它是如何工作的。即使您想展示如何巧妙地将多个功能链接在同一行上。然而,这样你是在写一段愚蠢的代码。如果你用复杂的思维写这段代码,你以后看这段代码就很难看懂。保持代码简单,尤其是在Node的异步代码中。当然有left-pad事件,但它只影响依赖left-pad模块的项目,11分钟后发布了替代品。代码最小化的好处超过了它的缺点。npm已经改变了它的发布策略,任何重要的项目都应该使用缓存或私有源(作为临时解决方案)。使用异步编程只需要Node.js中的一小部分同步代码。此代码的大部分用于命令行工具或其他非Web应用程序相关的脚本。大多数Node开发人员编写Web应用程序,因此使用异步代码可以避免阻塞站点。例如,当你在编写数据库脚本或不需要控制并行度的任务时,以下可能没问题:但是当你创建一个web应用程序时,以下更好:不同的是你是否需要编写并发(通常是长时间运行)或非并发(短期运行)系统。根据经验,始终在Node.js中使用异步代码。避免require阻塞Node有一个使用CommonJS模块格式的简单模块加载系统。它基于require函数,可以方便的在不同的文件中引入模块。与AMD/requirejs不同,Node/CommonJS模块是同步加载的。require的工作方式是引入一个模块或者一个文件导出的内容:但是大多数开发者并不知道require会被缓存。因此,只要解析后的文件名没有发生剧烈变化(比如npm模块不存在的情况),模块的代码只会被执行一次,并存储在变量中(在当前进程中)。这是一个很好的优化。当然,即使有缓存,你最好把你的require语句放在最前面。下面的代码只有在路由中真正使用到axios模块时才会加载。/connect会很慢,因为它需要在发送请求时加载模块。一种更好、更高效的方法是在服务定义之前而不是在路由中导入模块:知道require将被缓存我已经在上一节中提到require将被缓存,但有趣的是我们在模块中.exports也会有代码。例如:从中我们了解到某些代码只会运行一次,您可以使用此功能来优化您的代码。始终检查错误Node不是Java。在Java中,您可以抛出错误,因为如果发生错误,您不希望应用程序继续执行。在Java中,您只需在外层使用一个简单的try...catch就可以处理多个错误。但在Node中情况并非如此。由于Node使用了事件循环和异步执行,所以发生的任何错误都会脱离错误处理程序的上下文(例如try...catch),下面的在Node中是没用的:但是try...catch可以使用在同步代码中。之前的代码片段可以重构得更好:如果我们不能将请求的返回内容包装在一个try...catch中,那么我们就没有办法处理请求错误。Node的开发者通过在返回参数中添加错误来解决这个问题。因此,我们需要在每次回调中手动处理错误。可以检查这些错误(判断error不为null),然后将错误信息显示给用户或者在客户端显示并记录,也可以通过调用回调传递error参数传递给回调错误返回到上层调用堆栈(如果调用堆栈顶部有另一个回调函数)。一个小技巧是您可以使用okay库。您可以像下面的示例一样使用它,以避免手动检查回调地狱(你好,回调地狱)中的错误。返回回调或使用if...elseNode是并行的。但是如果你不够小心,就会因为这个特性而出现bug。为了安全起见,应该使用return来终止代码的继续执行:这样可以避免由于代码逻辑处理不当导致一些不应该执行的内容(或错误)被执行。确保使用return来防止代码继续。监听错误事件Node中几乎所有的类/对象都有事件分发器(观察者模式)和广播错误事件。这是一个很好的功能,它允许开发人员在这些讨厌的错误产生巨大后果之前捕获它们。养成通过.on()创建错误事件监听器的好习惯:对你的npm比较了解的Node和前端开发者都知道,在安装模块的时候,使用--save会安装到package中。json包含一个包含模块版本信息的条目。当然还有--save-dev可以用来安装devDependencies(生产环境不需要的模块)。但是您知道是否可以使用-S和-D来代替--save和--save-dev吗?答案是肯定的。安装模块时,需要删除-S和-D自动添加到模块版本号的^标记。否则,当你使用npminstall(或npmi)安装模块时,它会自动拉取最新的镜像(版本号的第二位)。例如,v6.1.0是v6.2.0的镜像分支。npm团队推荐使用semver,但你最好不要。npm团队相信开源开发者会遵守semver,所以他们会在npm安装时自动添加^。没有人能保证这一点,因此最好锁定您的版本号。更好的方法是使用shrinkwrap:npmshrinkwrap将生成一个包含特定版本依赖项的文件。
