Node.js最佳实践:来自Node大师的启示
10 Node.js最佳实践:来自Node大师的启示由客座作者撰写Azat马尔丹.必威西盟体育网页登录SitePoint的客座文章旨在为您带来来自网络社区的著名作家和演讲者的精彩内容。
在我之前的文章中在2017年成为更好的节点开发人员的10个技巧,我介绍了10个Node.js技巧、技巧和技术,你现在可以应用到你的代码中。这篇文章延续了这一思路,提供了另外10个最佳实践,帮助您将Node技能提升到一个新的水平。这就是我们要讲的内容:
- 使用npm脚本-当你可以用npm脚本和Node更好地组织它们时,就停止写bash脚本。例如,
NPM运行构建
,开始
而且测验
.当Node开发人员查看一个新项目时,npm脚本就像是唯一的真相来源。 - 使用env变量——利用
process.env.NODE_ENV
通过将其设置为发展
,或生产
.有些框架也会使用这个变量,所以要遵守约定。 - 理解事件循环- - - - - -
setImmediate ()
不是即时的nextTick ()
不是下一个。使用setImmediate ()
或setTimeout ()
将cpu密集型任务卸载到下一个事件循环周期。 - 使用函数继承-避免陷入无脑的争论,以及像一些最多产的Node贡献者那样,只使用函数继承来调试和理解原型继承或类的脑力消耗陷阱。
- 恰当地命名事物-给出有意义的名称,作为文档。另外,请不要使用大写的文件名,如果需要,可以使用破折号。文件名中的大写字母不仅看起来奇怪,而且会导致跨平台问题吗.
- 考虑不要使用JavaScriptES6/7是一个可怜的补充,它是在6年的会议中诞生的,当时我们已经有了一个更好的JavaScript CoffeeScript。如果你想更快地发布代码,就使用它,不要浪费时间争论
var
/常量
/让
分号,类
还有其他论点。 - 提供本地代码-使用编译器时,提交原生JS代码(编译的结果),这样你的项目就可以在没有编译的情况下运行
- 使用gzip——咄!
npm i压缩-S
和健全的日志记录-不是太多,也不是太少,取决于环境。npm i morgan -S
- 按比例增加-从Node开发的第一天开始考虑集群和无状态服务。使用pm2或strongloop的集群控件
- 缓存的请求-通过将Node服务器隐藏在静态文件服务器(如nginx和/或请求级缓存(如Varnish缓存和CDN缓存)后面,获得最大的果汁。
我们把它们平分,分别看一下。好吗?
使用npm脚本
现在,为构建、测试、最重要的是启动应用程序创建npm脚本几乎是一个标准。这是Node开发人员遇到新Node项目时首先考虑的地方。有些人(1,2,3.,4)甚至抛弃了Grunt、Gulp等,转而使用更低级但更可靠的npm脚本。我完全能理解他们的论点。考虑到npm脚本有pre和post钩子,你可以达到一个非常复杂的自动化水平:
“脚本”:{“预设”:“节点prepare.js”,“postintall”:“节点clean.js”,“构建”:“webpack”,“postbuild”:“节点index.js”,“postversion”:“npm发布”}
通常在为前端开发时,您希望运行两个或多个监视进程来重新构建代码。例如,一个用于webpack,另一个用于nodemon。你可以用& &
因为第一个命令不会释放提示符。然而,有一个方便的模块叫做同时它可以生成多个进程并同时运行它们。
此外,安装开发命令行工具,如webpack, nodemon, gulp, Mocha等。在本地避免冲突。你可以指出/ node_modules /。bin /摩卡
例如,将这一行添加到bash/zsh配置文件(PATH!):
出口路径=”。/ node_modules /。斌:美元的路径"
使用环境变量
即使在项目的早期阶段也要利用环境变量,以确保不泄漏敏感信息,并从一开始就正确地构建代码。此外,一些库和框架(我知道Express肯定是这样做的)会引入类似于NODE_ENV
来改变他们的行为。设置为生产
.设置你的MONGO_URI
而且API_KEY
还有价值观。您可以创建一个shell文件(例如。start.sh
),并将其添加到.gitignore
:
NODE_ENV=生产MONGO_URL=蒙戈:/ / localhost: 27017 /账户API_KEY=Lolz nodemon index.js
Nodemon也有一个配置文件,你可以把你的env vars (例子):
{“env”:{“NODE_ENV”:“生产”,“MONGO_URL”:“mongo: / / localhost: 27017 /账户”}}
理解事件循环
强大而聪明的人事件循环是什么使Node如此快速和聪明,利用所有的时间,将浪费在等待输入和输出任务完成。因此,Node非常擅长优化I/ o约束系统。
如果您需要执行一些cpu密集型的任务(例如,计算、密码散列或压缩),那么除了为这些cpu任务生成新进程之外,您可能还需要使用setImmediate ()
或setTimeout ()
-它们回调中的代码将在下一个事件循环中继续。nextTick ()
作品在同一周期相反的名称。啊!
这是Bert Belder的图表,他负责事件循环。他清楚地知道事件循环是如何工作的!
使用函数继承
JavaScript支持原型继承,即对象从其他对象继承。的类
操作符也被添加到ES6语言中。然而,与函数继承相比,它明显复杂。大多数Node大师更喜欢后者的简单性。它是由一个简单的函数工厂模式实现的,并且不需要使用原型
,新
或这
.因为在函数继承中,每个对象都使用自己的方法副本,所以当您更新原型时(导致所有实例也发生变化)没有隐式影响。
考虑一下来自TJ Holowaychuk的代码,他是Express、Mocha、Connect、Superagent和其他几十个Node模块的幕后天才。Express使用函数继承(完整源代码):
出口=模块.出口=createApplication;/ /……函数createApplication(){var应用程序=函数(要求的事情,res,下一个){应用程序.处理(要求的事情,res,下一个);};mixin(应用程序,EventEmitter.原型,假);mixin(应用程序,原型,假);应用程序.请求={__proto__:要求的事情,应用程序:应用程序};应用程序.响应={__proto__:res,应用程序:应用程序};应用程序.初始化();返回应用程序;}
客观地说,核心Node模块大量使用原型继承。如果你遵循这个模式,确保你知道它是如何工作的。你可以阅读更多JavaScript继承模式在这里。
恰当地命名事物
这一点是显而易见的。好的名字可以作为文档。你喜欢哪一种?
常量德克斯特=需要(“摩根”)/ /……应用程序.使用(德克斯特(“开发”))//下一个季节是什么时候?
我不知道是什么德克斯特
在做什么时我只看着app.use ()
.换个更有意义的名字怎么样:
常量日志记录器=需要(“摩根”)/ /……应用程序.使用(日志记录器(“开发”))/ /啊哈!
同样,文件名必须正确地反映其中代码的目的。如果你看一下自由
Node (GitHub链接),其中所有核心模块都与平台捆绑在一起,然后你会看到文件/模块的清晰命名(即使你不是很熟悉所有核心模块):
Events.js fs.js http.js http.js module.js net.js os.js path.js process.js punycode.js querystring.js
内部模块用下划线(_debugger.js
,_http_agent.js
,_http_client.js
)就像代码中的方法和变量一样。这有助于警告开发人员,这是一个内部接口,如果你正在使用它,你是自己的-不要抱怨,如果它被重构甚至删除。
考虑不要使用JavaScript
嗯?你刚才看对了吗?但管他呢?是的。这是正确的。即使在ES6和ES2016/ES7添加的两个特性中,JavaScript仍然有它的怪癖。除了JavaScript,还有其他选择,您或您的团队可以通过很少的设置受益。根据专业水平和应用程序的性质,使用它可能会更好打印稿或流提供强类型。另一方面,还有榆树或ClojureScript的它们是纯功能性的。CoffeeScript是另一个伟大的和经过战斗考验的选择。你可以看看省2.0也
当您只需要几个宏(宏允许您这样做)时构建正是你想要的语言),而不是一门全新的语言,然后再考虑Sweet.js它将做到这一点-允许您编写生成代码的代码。
如果你选择非javascript路线,请仍然包含你的编译代码,因为一些开发人员可能不太理解你的语言,无法正确地构建它。例如,VS Code是最大的TypeScript项目之一,可能在Angular 2之后,而Code使用TypeScript为Node的核心模块打上类型补丁。在vscode /节点/ / src / vs /基地
的vscode回购(链接),您可以看到熟悉的模块名称,如加密
,过程
等,但与ts
扩展。还有其他的ts
文件在回购。然而,他们也包括vscode /构建
使用本地JavaScript代码。
了解Express中间件
Express是一个非常优秀和成熟的框架。它的聪明之处在于允许无数其他模块配置它的行为。因此,您需要了解最常用的中间件如何使用.所以为什么不抓住我的快递小抄.我列出了主要的中间件模块。例如,npm i压缩-S
将通过压缩响应来降低下载速度。记录器(小的)
或记录器(共同的)
将分别提供更少(dev)或更多(prod)日志。
按比例增加
Node在异步方面很出色,因为它的非阻塞I/O,并且它保持了这种简单的异步编码方式,因为只有一个线程。这是一个尽早开始扩展的机会,甚至可以从第一行代码开始。这是核心集群
模块,这将允许您垂直扩展没有太多的问题。然而,更好的方法是使用工具,如pm2或StrongLoop的集群控件.
例如,你可以从pm2开始:
npmI -g pm2
然后你可以启动同一个服务器的四个实例:
Pm2启动server.js -i4
对于Docker, pm2 version 2+有pm2-docker
.所以你的Dockerfile可以是这样的:
#……运行npm安装pm2 -g CMD[“pm2-docker”,“app.js”]
官方的Alpine Linux pm2镜像在码头工人中心.
缓存的请求
这是一个DevOps的最佳实践,它将允许你从你的Node实例中获得更多的能量(你可以用pm2或类似的方法获得不止一个,见上文)。方法是让Node服务器做应用程序的事情,比如发出请求、处理数据和执行业务逻辑,并将静态文件的流量卸载到另一个web服务器(如Apache httpd或Nginx)。同样,你可能应该使用Docker进行设置:
拷贝nginx.conf /etc/nginx/nginx.conf
我喜欢使用Docker组合来让多个容器(nginx, Node, Redis, MongoDB)相互协作。例如:
Web: build: ./应用程序卷:-”。/ app: / src /应用程序”港口:“3030:3000”链接:“db:复述”命令:pm2-docker app/server.js nginx: restart: always build: ./nginx/ ports: -“80:80”Volumes:—/www/public volumes_from:—web links:—web:web db: image: redis
总结
在这个开源软件的时代,没有理由不学习公开的、可信的、经过测试的代码。你不需要在核心圈子里就能进去。学习从不停止,我相信很快我们就会有不同的最佳实践,基于我们将经历的失败和成功。它们是有保证的。
最后,我想写一下软件是如何吞噬世界的,JavaScript是如何吞噬软件的……有很多很棒的东西,比如每年的标准发布,很多很多的npm模块,工具和会议……但我将以一句警告的话结束。
我看到越来越多的人在追逐下一个新的框架或语言。这是闪光物体综合症。他们每周学习一个新的库,每个月学习一个新的框架。他们会不由自主地查看Twitter、Reddit、Hacker News和JS Weekly。他们利用JavaScript世界中压倒性的活动水平来拖延。他们有空白的GitHub公开历史记录。
学习新东西是好的,但不要把它和实际建造东西混淆了。真正重要的和能支付你薪水的是建造东西。停止工程.你不是在打造下一个Facebook。承诺vs.生成器vs.异步等待对我来说是一个没有意义的问题,因为当有人在讨论中回复线程时,我已经写了我的回调(并且使用CoffeeScript比普通ES5/6/7快2倍!)
最后的最佳实践是使用最佳实践,而最佳中的最佳是掌握基础知识。阅读源代码,尝试代码中的新东西,最重要的是自己写大量的代码。现在,在这一点上,停止阅读并发布重要的代码!
如果这篇文章还不够,这里还有一些关于Node最佳实践的阅读:
- https://必威滚blog.risingstack.com/nodejs-at-scale-npm-best-practices
- https://devcenter.heroku.com/articles/node-best-practices
- https://必威滚blog.risingstack.com/node-js-best-practices
- https://expressjs.com/en/advanced/best-practice-performance.html
- https://www.codementor.io/nodejs/tutorial/nodejs-best-practices