node.js使用手册
Note: you can get a PDF, ePub, or Mobi version of this handbook for easier reference, or for reading on your Kindle or tablet.
注意:您可以获取本手册的PDF,ePub或Mobi版本,以方便参考或在Kindle或平板电脑上阅读。
This handbook is a getting started guide to Node.js, the server-side JavaScript runtime environment.
本手册是服务器端JavaScript运行时环境Node.js的入门指南。
Node.js is a runtime environment for JavaScript that runs on the server.
Node.js是在服务器上运行JavaScript的运行时环境 。
Node.js is open source, cross-platform, and since its introduction in 2009, it got hugely popular and now plays a significant role in the web development scene. If GitHub stars are one popularity indication factor, having 58000+ stars means being very popular.
Node.js是开放源代码,跨平台的,自2009年问世以来,它非常受欢迎,现在在Web开发领域中发挥着重要作用。 如果GitHub星级是一个受欢迎程度的指标,那么拥有58000多个星级意味着非常受欢迎。
Node.js runs the V8 JavaScript engine, the core of Google Chrome, outside of the browser. Node.js is able to leverage the work of the engineers that made (and will continue to make) the Chrome JavaScript runtime blazing fast, and this allows Node.js to benefit from the huge performance improvements and the Just-In-Time compilation that V8 performs. Thanks to this, JavaScript code running in Node.js can become very performant.
Node.js在浏览器外部运行V8 JavaScript引擎(Google Chrome的核心)。 Node.js能够利用使(并将继续进行)Chrome JavaScript运行时快速发展的工程师的工作,这使Node.js能够从巨大的性能改进和即时编译中受益。 V8执行。 因此,在Node.js中运行JavaScript代码可以变得非常出色。
A Node.js app is run by a single process, without creating a new thread for every request. Node provides a set of asynchronous I/O primitives in its standard library that will prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making a blocking behavior an exception rather than the normal.
Node.js应用程序由单个进程运行,无需为每个请求创建新线程。 Node在其标准库中提供了一组异步I / O原语,这些原语将防止JavaScript代码被阻塞,并且通常,Node.js中的库是使用非阻塞范式编写的,从而使阻塞行为成为异常而非常规行为。
When Node.js needs to perform an I/O operation, like reading from the network, access a database or the filesystem, instead of blocking the thread Node.js will resume the operations when the response comes back, instead of wasting CPU cycles waiting.
当Node.js需要执行I / O操作(例如从网络读取,访问数据库或文件系统)而不是阻塞线程时,Node.js将在响应返回时恢复操作,而不是浪费CPU等待周期。
This allows Node.js to handle thousands of concurrent connections with a single server without introducing the burden of managing threads concurrency, which would be a major source of bugs.
这使Node.js可以在一台服务器上处理数千个并发连接,而不会带来管理线程并发的负担,这将是漏洞的主要来源。
Node.js has a unique advantage because millions of frontend developers that write JavaScript for the browser are now able to run the server-side code and frontend-side code without the need to learn a completely different language.
Node.js具有独特的优势,因为数百万为浏览器编写JavaScript的前端开发人员现在可以运行服务器端代码和前端代码,而无需学习完全不同的语言。
In Node.js the new ECMAScript standards can be used without problems, as you don’t have to wait for all your users to update their browsers — you are in charge of deciding which ECMAScript version to use by changing the Node.js version, and you can also enable specific experimental features by running Node with flags.
在Node.js中,可以毫无问题地使用新的ECMAScript标准,因为您不必等待所有用户更新其浏览器-您可以通过更改Node.js版本来决定要使用哪个ECMAScript版本,并且您还可以通过运行带有标志的Node来启用特定的实验功能。
With its simple structure, the node package manager (npm) helped the ecosystem of Node.js proliferate. Now the npm registry hosts almost 500,000 open source packages you can freely use.
凭借其简单的结构,节点包管理器 ( npm )帮助Node.js的生态系统激增。 现在, npm注册表托管了将近500,000个您可以自由使用的开源软件包。
The most common example Hello World of Node.js is a web server:
最常见的Node.js的Hello World示例是Web服务器:
const http = require('http')
const hostname = '127.0.0.1'const port = 3000
const server = http.createServer((req, res) => { res.statusCode = 200 res.setHeader('Content-Type', 'text/plain') res.end('Hello World\n')})
server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`)})
To run this snippet, save it as a server.js
file and run node server.js
in your terminal.
要运行此代码段,请将其另存为server.js
文件,然后在终端中运行node server.js
。
This code first includes the Node.js http
module.
此代码首先包含Node.js http
模块 。
Node.js has an amazing standard library, including a first-class support for networking.
Node.js具有出色的标准库 ,包括对网络的一流支持。
The createServer()
method of http
creates a new HTTP server and returns it.
http
的createServer()
方法创建一个新的HTTP服务器并返回它。
The server is set to listen on the specified port and hostname. When the server is ready, the callback function is called, in this case informing us that the server is running.
服务器设置为侦听指定的端口和主机名。 服务器准备好后,将调用回调函数,在这种情况下,通知我们服务器正在运行。
Whenever a new request is received, the request
event is called, providing two objects: a request (an http.IncomingMessage
object) and a response (an http.ServerResponse
object).
每当接收到新请求时,都会调用request
事件 ,并提供两个对象:一个请求(一个http.IncomingMessage
对象)和一个响应(一个http.ServerResponse
对象)。
These 2 objects are essential to handle the HTTP call.
这两个对象对于处理HTTP调用至关重要。
The first provides the request details. In this simple example, this is not used, but you could access the request headers and request data.
第一个提供请求详细信息。 在这个简单的示例中,没有使用它,但是您可以访问请求标头和请求数据。
The second is used to return data to the caller.
第二个用于将数据返回给调用方。
In this case with:
在这种情况下:
res.statusCode = 200
We set the statusCode
property to 200
, to indicate a successful response.
我们将statusCode
属性设置为200
,以指示成功的响应。
We set the Content-Type header:
我们设置Content-Type标头:
res.setHeader('Content-Type', 'text/plain')
…and we end close the response, adding the content as an argument to end()
:
…然后结束响应,将内容作为参数添加到end()
:
res.end('Hello World\n')
Node.js is a low-level platform. To make things easier and more interesting for developers, thousands of libraries were built upon Node.js.
Node.js是一个低级平台。 为了使开发人员更轻松,更有趣,在Node.js上构建了数千个库。
Many of those established over time as popular options. Here is a non-comprehensive list to the ones I consider very relevant and worth learning:
随着时间的流逝,其中许多已成为受欢迎的选择。 这是我认为非常相关且值得学习的列表,不全面:
Express
表达
One of the most simple yet powerful ways to create a web server. Its minimalist approach and unopinionated focus on the core features of a server is key to its success.
创建Web服务器的最简单但功能最强大的方法之一。 它的极简方法和对服务器核心功能的专心致志是其成功的关键。
Meteor
流星
An incredibly powerful full-stack framework, empowering you with an isomorphic approach to building apps with JavaScript and sharing code on the client and the server. Once an off-the-shelf tool that provided everything, it now integrates with front-end libraries such as
一个功能强大的全栈框架,使您可以采用同构方法来使用JavaScript构建应用程序并在客户端和服务器上共享代码。 一旦提供了所有功能的现成工具,它现在就可以与诸如
React, Vue and Angular. Meteor can be used to create mobile apps as well.
React , Vue和Angular 。 流星也可以用来创建移动应用程序。
Koa
考阿
Built by the same team behind Express, Koa aims to be even simpler and smaller, building on top of years of knowledge. The new project was born out of the need to create incompatible changes without disrupting the existing community.
Koa由Express背后的同一团队构建,其目标是在多年的知识基础上,变得更小,更小。 新项目的诞生是出于创建不兼容的更改而又不破坏现有社区的需要。
Next.js
Next.js
This is a framework to render server-side rendered
这是渲染服务器端渲染的框架
React applications.
React应用程序。
Micro
微
This is a very lightweight server to create asynchronous HTTP microservices.
这是一个非常轻量级的服务器,用于创建异步HTTP微服务。
Socket.io
套接字
This is a real-time communication engine to build network applications.
这是用于构建网络应用程序的实时通信引擎。
Believe it or not, Node.js is just 9 years old.
信不信由你,Node.js才9岁。
In comparison, JavaScript is 23 years old and the web as we know it (after the introduction of Mosaic) is 25 years old.
相比之下,JavaScript已有23年的历史了,而我们所知道的网络(在Mosaic引入之后)已有25年的历史了。
9 years is such a little amount of time for a technology, but Node.js seems to have been around forever.
9年对于技术来说是很少的时间,但是Node.js似乎永远存在。
I’ve had the pleasure to work with Node.js since the early days when it was just 2 years old, and despite the little information available, you could already feel it was a huge thing.
从成立仅2年的早期开始,我就很高兴与Node.js一起工作,尽管可以获得的信息很少,但您已经可以感觉到这是一件大事。
In this section, I want to draw the big picture of Node.js in its history, to put things in perspective.
在本节中,我想勾勒出Node.js的历史概况,以便对事物进行透视。
JavaScript is a programming language that was created at Netscape as a scripting tool to manipulate web pages inside their browser, Netscape Navigator.
JavaScript是一种在Netscape中创建的编程语言,它是一种脚本工具,用于在其浏览器Netscape Navigator中操纵网页。
Part of the business model of Netscape was to sell Web Servers, which included an environment called “Netscape LiveWire”, which could create dynamic pages using server-side JavaScript. So the idea of server-side JavaScript was not introduced by Node.js, it’s old just like JavaScript — but at the time it was not successful.
Netscape的业务模型的一部分是出售Web服务器,其中包括一个称为“ Netscape LiveWire”的环境,该环境可以使用服务器端JavaScript创建动态页面。 因此,Node.js并没有引入服务器端JavaScript的想法,它像JavaScript一样古老,但是当时还没有成功。
One key factor that led to the rise of Node.js was timing. A few years ago, JavaScript was starting to be considered a serious language, thanks for the “Web 2.0” applications that showed the world what a modern experience on the web could be like (think Google Maps or GMail).
导致Node.js兴起的一个关键因素是计时。 几年前,由于“ Web 2.0”应用程序向世界展示了现代的Web体验(例如Google Maps或GMail),JavaScript开始被认为是一种严肃的语言。
The JavaScript engines performance bar raised considerably thanks to the browser competition battle, which is still going strong. Development teams behind each major browser work hard every day to give us better performance, which is a huge win for JavaScript as a platform. Chrome V8, the engine that Node.js uses under the hood, is one of those and in particular it’s the Chrome JavaScript engine.
由于浏览器竞争的激烈,JavaScript引擎的性能标准大为提高,但该竞争仍在继续。 每个主要浏览器背后的开发团队每天都在努力工作,以提高性能,这对于JavaScript作为平台是一个巨大的胜利。 Node.js在后台使用的Chrome V8引擎就是其中之一,尤其是Chrome JavaScript引擎。
But of course, Node.js is not popular just because of pure luck or timing. It introduced much innovative thinking on how to program in JavaScript on the server.
但是,当然,仅由于运气或时机原因,Node.js并不流行。 它引入了有关如何在服务器上使用JavaScript编程的许多创新思想。
Node.js is born
Node.js诞生了
The first form of npm is created
创建npm的第一种形式
Express is born
快递出生
Socket.io is born
Socket.io诞生了
npm hits 1.0
npm达到1.0
Big companies start adopting Node: LinkedIn, Uber
大公司开始采用Node: LinkedIn , Uber
Hapi is born
哈皮出生
Adoption continues very rapidly
采纳非常Swift
First big blogging platform using Node.js: Ghost
第一个使用Node.js的大型博客平台: Ghost
Koa is born
Koa出生
Big drama: IO.js is a major fork of Node.js, with the goal of introducing ES6 support and move faster
重大事件 : IO.js是Node.js的主要分支,旨在引入ES6支持并加快迁移速度
The Node.js Foundation is born
Node.js Foundation诞生了
IO.js is merged back into Node.js
IO.js合并回Node.js
npm introduces private modules
npm引入了私有模块
Node 4 (no 1, 2, 3 versions were previously released)
节点4 (之前没有发布1、2、3个版本)
The leftpad incident
左垫事件
Yarn is born: Node 6
纱线诞生:节点6
npm focuses more on security: Node 8
npm更加关注安全性:节点8
HTTP/2
HTTP / 2
V8 introduces Node in its testing suite, officially making Node a target for the JavaScript engine, in addition to Chrome
V8在其测试套件中引入了Node,除了Chrome之外,它还正式使Node成为JavaScript引擎的目标
3 billion npm downloads every week
每周30亿次npm下载
Node 10
节点10
ES modules.
ES模块 。
mjs experimental support
mjs实验支持
Node.js can be installed in different ways. This post highlights the most common and convenient ones.
Node.js可以通过不同的方式进行安装。 这篇文章重点介绍了最常见,最方便的文章。
Official packages for all the major platforms are available here.
所有主要平台的官方软件包都可在此处获得 。
One very convenient way to install Node.js is through a package manager. In this case, every operating system has its own.
一种非常方便的安装Node.js的方法是通过程序包管理器。 在这种情况下,每个操作系统都有其自己的。
On macOS, Homebrew is the de-facto standard, and — once installed — allows to install Node.js very easily, by running this command in the CLI:
在macOS上, Homebrew是事实上的标准,并且一旦安装,就可以通过在CLI中运行以下命令来非常轻松地安装Node.js:
brew install node
Other package managers for Linux and Windows are listed here.
这里列出了其他用于Linux和Windows的软件包管理器。
nvm is a popular way to run Node.js. It allows you to easily switch the Node.js version, and install new versions to try and easily rollback if something breaks, for example.
nvm是运行Node.js的一种流行方法。 例如,它使您可以轻松切换Node.js版本,并安装新版本以尝试并轻松回滚。
It is also very useful to test your code with old Node.js versions.
使用旧的Node.js版本测试代码也非常有用。
My suggestion is to use the official installer if you are just starting out and you don’t use Homebrew already. Otherwise, Homebrew is my favorite solution.
我的建议是,如果您刚刚开始并且还没有使用Homebrew,请使用官方安装程序。 否则,自制软件是我最喜欢的解决方案。
If you are just starting out with JavaScript, how deeply do you need to know the language?
如果您刚开始使用JavaScript,则需要深入了解该语言?
As a beginner, it’s hard to get to a point where you are confident enough in your programming abilities.
作为一个初学者,很难达到对编程能力足够自信的地步。
While learning to code, you might also be confused at where does JavaScript end, and where Node.js begins, and vice versa.
在学习编码的同时,您可能还会对JavaScript的结束位置,Node.js的起始位置以及相反的位置感到困惑。
I would recommend you to have a good grasp of the main JavaScript concepts before diving into Node.js:
我建议您在深入研究Node.js之前先掌握主要JavaScript概念:
With those concepts in mind, you are well on your road to become a proficient JavaScript developer, in both the browser and in Node.js.
考虑到这些概念,无论是在浏览器还是在Node.js中,您都将成为一名熟练JavaScript开发人员。
The following concepts are also key to understand asynchronous programming, which is one fundamental part of Node.js:
以下概念也是理解异步编程的关键,异步编程是Node.js的基本组成部分:
Luckily I wrote a free ebook that explains all those topics, and it’s called JavaScript Fundamentals. It’s the most compact resource you’ll find to learn all of this.
幸运的是,我写了一本免费的电子书来解释所有这些主题,它被称为JavaScript基础 。 这是您可以找到的最紧凑的资源。
How writing JavaScript application in Node.js differs from programming for the Web inside the browser.
在Node.js中编写JavaScript应用程序与在浏览器中进行Web编程的方式有所不同。
Both the browser and Node use JavaScript as their programming language.
浏览器和Node均使用JavaScript作为其编程语言。
Building apps that run in the browser is a completely different thing than building a Node.js application.
构建在浏览器中运行的应用程序与构建Node.js应用程序完全不同。
Despite the fact that it’s always JavaScript, there are some key differences that make the experience radically different.
尽管事实始终是JavaScript,但仍存在一些关键差异,使体验完全不同。
A front-end developer that writes Node.js apps has a huge advantage — the language is still the same.
编写Node.js应用程序的前端开发人员具有巨大的优势-语言仍然相同。
You have a huge opportunity because we know how hard it is to fully, deeply learn a programming language. By using the same language to perform all your work on the web — both on the client and on the server — you’re in a unique position of advantage.
您拥有巨大的机会,因为我们知道全面深入地学习编程语言是多么困难。 通过使用相同的语言在客户端和服务器上在Web上执行所有工作,您将处于独特的优势地位。
What changes is the ecosystem.
改变的是生态系统。
In the browser, most of the time what you are doing is interacting with the DOM, or other Web Platform APIs like Cookies. Those do not exist in Node.js, of course. You don’t have the document
, window
and all the other objects that are provided by the browser.
在浏览器中,大多数时候您正在做的是与DOM或其他Web平台API(例如Cookies)进行交互。 当然,那些在Node.js中不存在。 您没有document
, window
以及浏览器提供的所有其他对象。
And in the browser, we don’t have all the nice APIs that Node.js provides through its modules, like the file system access functionality.
而且在浏览器中,我们没有Node.js通过其模块提供的所有不错的API,例如文件系统访问功能。
Another big difference is that in Node.js you control the environment. Unless you are building an open source application that anyone can deploy anywhere, you know which version of Node.js you will run the application on. Compared to the browser environment, where you don’t get the luxury to choose what browser your visitors will use, this is very convenient.
另一个很大的不同是,在Node.js中,您可以控制环境。 除非您构建任何人都可以在任何地方部署的开源应用程序,否则您将知道将在哪个版本的Node.js上运行该应用程序。 与浏览器环境相比,在浏览器环境中,您无法选择访客会使用的浏览器,这非常方便。
This means that you can write all the modern ES6–7–8–9 JavaScript that your Node version supports.
这意味着您可以编写您的Node版本支持的所有现代ES6–7–8–9 JavaScript。
Since JavaScript moves so fast, but browsers can be a bit slow and users a bit slow to upgrade — sometimes on the web, you are stuck using older JavaScript/ECMAScript releases.
由于JavaScript的移动速度如此之快,但浏览器可能会变慢,而用户的升级会变慢-有时在网络上,您会被困在使用较旧JavaScript / ECMAScript版本。
You can use Babel to transform your code to be ES5-compatible before shipping it to the browser, but in Node.js, you won’t need that.
您可以使用Babel将代码转换为与ES5兼容,然后再将其交付给浏览器,但是在Node.js中,则不需要这样做。
Another difference is that Node.js uses the CommonJS module system, while in the browser we are starting to see the ES Modules standard being implemented.
另一个区别是Node.js使用CommonJS模块系统,而在浏览器中,我们开始看到正在实现ES模块标准。
In practice, this means that for the time being you use require()
in Node.js and import
in the browser.
实际上,这意味着您暂时在Node.js中使用require()
并在浏览器中import
。
V8 is the name of the JavaScript engine that powers Google Chrome. It’s the thing that takes our JavaScript and executes it while browsing with Chrome.
V8是支持Google Chrome浏览器JavaScript引擎的名称。 这是需要我们JavaScript并在使用Chrome浏览器时执行它的东西。
V8 provides the runtime environment in which JavaScript executes. The DOM, and the other Web Platform APIs are provided by the browser.
V8提供了运行JavaScript的运行时环境。 DOM和其他Web平台API由浏览器提供。
The cool thing is that the JavaScript engine is independent by the browser in which it’s hosted. This key feature enabled the rise of Node.js. V8 was chosen for being the engine chosen by Node.js back in 2009, and as the popularity of Node.js exploded, V8 became the engine that now powers an incredible amount of server-side code written in JavaScript.
很棒的事情是JavaScript引擎独立于托管它的浏览器。 这项关键功能推动了Node.js的兴起。 V8于2009年被选为Node.js的引擎,并且随着Node.js的爆炸性发展,V8成为了现在可以驱动大量用JavaScript编写的服务器端代码的引擎。
The Node.js ecosystem is huge and thanks to it V8 also powers desktop apps, with projects like Electron.
Node.js生态系统非常庞大,由于有了V8,V8还为桌面应用程序提供了支持,并支持Electron等项目。
Other browsers have their own JavaScript engine:
其他浏览器具有自己JavaScript引擎:
Firefox has Spidermonkey
Firefox拥有Spidermonkey
Safari has JavaScriptCore (also called Nitro)
Safari具有JavaScriptCore (也称为Nitro)
Edge has Chakra
边缘有脉轮
and many others exist as well.
还有很多其他的存在。
All those engines implement the ECMA ES-262 standard, also called ECMAScript, the standard used by JavaScript.
所有这些引擎都实现ECMA ES-262标准,也称为ECMAScript,JavaScript使用该标准。
V8 is written in C++, and it’s continuously improved. It is portable and runs on Mac, Windows, Linux and several other systems.
V8用C ++编写,并且不断改进。 它是便携式的,可在Mac,Windows,Linux和其他几个系统上运行。
In this V8 introduction, I will ignore the implementation details of V8. They can be found on more authoritative sites, including the V8 official site, and they change over time, often radically.
在此V8简介中,我将忽略V8的实现细节。 可以在更权威的网站(包括V8官方网站 )上找到它们,并且它们会随着时间而发生变化,通常会发生根本性变化。
V8 is always evolving, just like the other JavaScript engines around, to speed up the Web and the Node.js ecosystem.
与其他JavaScript引擎一样,V8也在不断发展以加速Web和Node.js生态系统。
On the web, there is a race for performance that’s been going on for years, and we (as users and developers) benefit a lot from this competition because we get faster and more optimized machines year after year.
在网络上,性能竞赛一直持续了多年,我们(作为用户和开发人员)从竞争中受益匪浅,因为我们年复一年地获得了更快,更优化的机器。
JavaScript is generally considered an interpreted language, but modern JavaScript engines no longer just interpret JavaScript, they compile it.
JavaScript通常被认为是一种解释语言,但是现代JavaScript引擎不再只是解释JavaScript,而是对其进行编译。
This happens since 2009 when the SpiderMonkey JavaScript compiler was added to Firefox 3.5, and everyone followed this idea.
自2009年将SpiderMonkey JavaScript编译器添加到Firefox 3.5以来,这种情况就发生了,每个人都遵循了这个想法。
JavScript is internally compiled by V8 with just-in-time (JIT) compilation to speed up the execution.
JavScript由V8内部进行实时编译(JIT),以加快执行速度。
This might seem counter-intuitive,. But since the introduction of Google Maps in 2004, JavaScript has evolved from a language that was generally executing a few dozens of lines of code to complete applications with thousands to hundreds of thousands of lines running in the browser.
这似乎违反直觉。 但是,自2004年推出Google Maps以来,JavaScript已经从一种通常执行数十行代码的语言演变为可以在浏览器中运行成千上万行的完整应用程序。
Our applications now can run for hours inside a browser, rather than being just a few form validation rules or simple scripts.
现在,我们的应用程序可以在浏览器中运行数小时,而不仅仅是一些表单验证规则或简单的脚本。
In this new world, compiling JavaScript makes perfect sense because while it might take a little bit more to have the JavaScript ready, once done it’s going to be much more performant that purely interpreted code.
在这个新世界中 ,编译JavaScript非常有意义,因为尽管准备好 JavaScript可能需要花费更多时间,但一旦完成,它将比纯解释代码具有更高的性能。
There are various ways to terminate a Node.js application.
有多种方法可以终止Node.js应用程序。
When running a program in the console you can close it with ctrl-C
, but what I want to discuss here is programmatically exiting.
在控制台中运行程序时,可以使用ctrl-C
其关闭,但是我这里要讨论的是通过编程退出。
Let’s start with the most drastic one, and see why you’re better off not using it.
让我们从最激烈的话题开始,看看为什么不使用它会更好。
The process
core module is provides a handy method that allows you to programmatically exit from a Node.js program: process.exit()
.
process
核心模块提供了一种方便的方法,使您可以以编程方式退出Node.js程序: process.exit()
。
When Node.js runs this line, the process is immediately forced to terminate.
当Node.js运行此行时,该过程立即被迫终止。
This means that any callback that’s pending, any network request still being sent, any file system access, or processes writing to stdout
or stderr
— all is going to be ungracefully terminated right away.
这意味着任何待处理的回调,仍在发送任何网络请求,任何文件系统访问或写入stdout
或stderr
进程-所有这些都将立即被非正常终止。
If this is fine for you, you can pass an integer that signals the operating system the exit code:
如果这对您来说很好,则可以传递一个整数,向操作系统发出退出代码:
process.exit(1)
By default the exit code is 0
, which means success. Different exit codes have different meaning, which you might want to use in your own system to have the program communicate to other programs.
默认情况下,退出代码为0
,表示成功。 不同的退出代码具有不同的含义,您可能希望在自己的系统中使用这些退出代码,以使程序与其他程序进行通信。
You can read more on exit codes here.
您可以在此处阅读有关退出代码的更多信息 。
You can also set the process.exitCode
property:
您还可以设置process.exitCode
属性:
process.exitCode = 1
and when the program will later end, Node.js will return that exit code.
当程序稍后结束时,Node.js将返回该退出代码。
A program will gracefully exit when all the processing is done.
完成所有处理后,程序将正常退出。
Many times with Node.js we start servers, like this HTTP server:
很多时候,我们使用Node.js启动服务器,例如HTTP服务器:
const express = require('express')const app = express()
app.get('/', (req, res) => { res.send('Hi!')})
app.listen(3000, () => console.log('Server ready'))
This program is never going to end. If you call process.exit()
, any currently pending or running request is going to be aborted. This is not nice.
这个程序永远不会结束。 如果您调用process.exit()
,那么任何当前挂起或正在运行的请求都将被中止。 这不好 。
In this case you need to send the command a SIGTERM
signal, and handle that with the process signal handler:
在这种情况下,您需要向该命令发送SIGTERM
信号,并使用过程信号处理程序进行处理:
Note: process
does not require a require
, it's automatically available.
注意: process
不需要require
,它是自动可用的。
const express = require('express')
const app = express()
app.get('/', (req, res) => { res.send('Hi!')})
app.listen(3000, () => console.log('Server ready'))
process.on('SIGTERM', () => { app.close(() => { console.log('Process terminated') })})
What are signals? Signals are a Portable Operating System Interface (POSIX) intercommunication system: a notification sent to a process in order to notify it of an event that occurred.
什么是信号? 信号是可移植操作系统接口(POSIX)互通系统:一种发送到进程的通知,用于将发生的事件通知给进程。
SIGKILL
is the signals that tells a process to immediately terminate, and would ideally act like process.exit()
.
SIGKILL
是告诉进程立即终止的信号,理想情况下,其行为类似于process.exit()
。
SIGTERM
is the signals that tells a process to gracefully terminate. It is the signal that's sent from process managers like upstart
or supervisord
and many others.
SIGTERM
是告诉进程正常终止的信号。 它是从流程管理者(例如upstart
或supervisord
以及其他许多人发出的信号。
You can send this signal from inside the program, in another function:
您可以在另一个函数中从程序内部发送此信号:
process.kill(process.pid, 'SIGTERM')
Or from another Node.js running program, or any other app running in your system that knows the PID of the process you want to terminate.
或从另一个正在运行的Node.js程序,或从系统中运行的其他任何知道您要终止的进程的PID的应用程序。
The process
core module of Node provides the env
property which hosts all the environment variables that were set at the moment the process was started.
Node的process
核心模块提供env
属性,该属性承载在启动进程时设置的所有环境变量。
Here is an example that accesses the NODE_ENV
environment variable, which is set to development
by default.
这是访问NODE_ENV
环境变量的示例,该环境变量默认情况下设置为development
。
process.env.NODE_ENV // "development"
Setting it to production
before the script runs will tell Node.js that this is a production environment.
在脚本运行之前将其设置为production
将告诉Node.js这是一个生产环境。
In the same way you can access any custom environment variable you set.
您可以用相同的方式访问您设置的任何自定义环境变量。
A Node.js application can be hosted in a lot of places, depending on your needs.
Node.js应用程序可以托管在很多地方,具体取决于您的需求。
Here is a non-exhaustive list of the options you can explore when you want to deploy your app and make it publicly accessible.
这是一份详尽的选项列表,您可以在要部署应用并使之公开访问时进行探索。
I will list the options from simplest and constrained to more complex and powerful.
我将列出从最简单的约束到更复杂和强大的选项。
Even if you have a dynamic IP, or you’re under a NAT, you can deploy your app and serve the requests right from your computer using a local tunnel.
即使您拥有动态IP或处于NAT下,也可以使用本地隧道从您的计算机部署应用程序并处理请求。
This option is suited for some quick testing, demo a product or sharing of an app with a very small group of people.
此选项适用于一些快速测试,演示产品或与极少数人共享应用程序。
A very nice tool for this, available on all platforms, is ngrok.
ngrok是在所有平台上都可用的一个非常好的工具。
Using it, you can just type ngrok PORT
and the PORT you want is exposed to the internet. You will get a ngrok.io domain, but with a paid subscription you can get a custom URL as well as more security options (remember that you are opening your machine to the public Internet).
使用它,您只需键入ngrok PORT
,所需的端口就会暴露在Internet上。 您将获得一个ngrok.io域,但是通过付费订阅,您可以获得一个自定义URL以及更多的安全选项(请记住,您正在向公共Internet打开计算机)。
Another service you can use is localtunnel.
您可以使用的另一项服务是localtunnel 。
Glitch is a playground and a way to build your apps faster than ever, and see them live on their own glitch.com subdomain. You cannot currently have a a custom domain, and there are a few restrictions in place, but it’s really great to prototype. It looks fun (and this is a plus), and it’s not a dumbed down environment — you get all the power of Node.js, a CDN, secure storage for credentials, GitHub import/export and much more.
Glitch是一个游乐场,可让您比以往更快地构建应用程序,并在自己的glitch.com子域中看到它们。 您目前无法拥有一个自定义域,并且有一些限制 ,但是原型制作真的很棒。 它看起来很有趣(这是一个加号),并且它不是一个愚蠢的环境-您可以获得Node.js的所有功能,CDN,用于凭证的安全存储,GitHub导入/导出等等。
Provided by the company behind FogBugz and Trello (and co-creators of Stack Overflow).
由FogBugz和Trello(以及Stack Overflow的共同创建者)背后的公司提供。
I use it a lot for demo purposes.
我经常将其用于演示目的。
Codepen is an amazing platform and community. You can create a project with multiple files, and deploy it with a custom domain.
Codepen是一个了不起的平台和社区。 您可以创建包含多个文件的项目,并使用自定义域进行部署。
A way to publish your apps, and have no server at all to manage, is Serverless. Serverless is a paradigm where you publish your apps as functions, and they respond on a network endpoint (also called FAAS — Functions As A Service).
无服务器是一种发布应用且完全无需管理服务器的方法。 无服务器是一种将应用程序发布为功能的范例,它们会在网络终结点上响应(也称为FAAS —功能即服务)。
To very popular solutions are:
最受欢迎的解决方案是:
Serverless Framework
无服务器框架
Standard Library
标准图书馆
They both provide an abstraction layer to publishing on AWS Lambda and other FAAS solutions based on Azure or the Google Cloud offering.
它们都提供了一个抽象层,可以在AWS Lambda和其他基于Azure或Google Cloud产品的FAAS解决方案上发布。
PAAS stands for Platform As A Service. These platforms take away a lot of things you should otherwise worry about when deploying your application.
PAAS代表平台即服务。 这些平台消除了许多您在部署应用程序时应担心的事情。
Zeit is an interesting option. You just type now
in your terminal, and it takes care of deploying your application. There is a free version with limitations, and the paid version is more powerful. You simply forget that there’s a server, you just deploy the app.
Zeit是一个有趣的选择。 您now
只需在终端中键入内容,它就可以部署您的应用程序。 有一个免费版本有限制,而付费版本则功能更强大。 您只是忘了有一个服务器,只是部署了该应用程序。
Nanobox
纳米盒
Heroku is an amazing platform.
Heroku是一个了不起的平台。
This is a great article on getting started with Node.js on Heroku.
这是一篇关于Heroku上Node.js入门的很棒的文章。
Azure is the Microsoft Cloud offering.
Azure是Microsoft Cloud产品。
Check out how to create a Node.js web app in Azure.
了解如何在Azure中创建Node.js Web应用程序 。
Google Cloud is an amazing structure for your apps.
Google Cloud对您的应用程序来说是一种了不起的结构。
They have a good Node.js Documentation Section.
他们有一个很好的Node.js文档部分 。
In this section you find the usual suspects, ordered from more user friendly to less user friendly:
在本节中,您将找到通常的可疑对象,从较高的用户友好程度到较低的用户友好程度进行排序:
Digital Ocean
数字海洋
Linode
Linode
Amazon Web Services, in particular I mention Amazon Elastic Beanstalk as it abstracts away a little bit the complexity of AWS.
尤其是Amazon Web Services ,我提到Amazon Elastic Beanstalk,因为它抽象了一点AWS的复杂性。
Since they provide an empty Linux machine on which you can work, there is no specific tutorial for these.
由于它们提供了可以在其上工作的空Linux计算机,因此没有针对它们的特定教程。
There are lots more options in the VPS category, those are just the ones I used and I would recommend.
VPS类别中还有更多选项,这些只是我使用的选项,我会建议您使用。
Another solution is to get a bare metal server, install a Linux distribution, connect it to the internet (or rent one monthly, like you can do using the Vultr Bare Metal service)
另一种解决方案是获得裸机服务器 ,安装Linux发行版,将其连接到Internet(或每月租用一个服务器,就像使用Vultr Bare Metal服务一样)
REPL stands for Read-Evaluate-Print-Loop, and it’s a great way to explore the Node.js features in a quick way.
REPL代表Read-Evaluate-Print-Loop,它是快速探索Node.js功能的好方法。
The node
command is the one we use to run our Node.js scripts:
node
命令是我们用来运行Node.js脚本的命令:
node script.js
If we omit the filename, we use it in REPL mode:
如果省略文件名,则在REPL模式下使用它:
node
If you try it now in your terminal, this is what happens:
如果您现在在终端中尝试,将发生以下情况:
❯ node>
the command stays in idle mode and waits for us to enter something.
该命令将保持空闲状态,并等待我们输入内容。
Tip: if you are unsure how to open your terminal, Google “How to open terminal on
提示 :如果不确定如何打开终端,请单击“如何在<您的操作系统>上打开终端”。
The REPL is waiting for us to enter some JavaScript code.
REPL正在等待我们输入一些JavaScript代码。
Start simple and enter:
从简单开始,然后输入:
> console.log('test')testundefined>
The first value, test
, is the output we told the console to print, then we get undefined which is the return value of running console.log()
.
第一个值test
是我们告诉控制台打印的输出,然后我们得到undefined,它是正在运行的console.log()
的返回值。
We can now enter a new line of JavaScript.
现在,我们可以输入一行新JavaScript。
The cool thing about the REPL is that it’s interactive.
REPL的优点在于它是交互式的。
As you write your code, if you press the tab
key the REPL will try to autocomplete what you wrote to match a variable you already defined or a predefined one.
在编写代码时,如果按tab
键,REPL将尝试自动完成编写的内容以匹配已定义的变量或预定义的变量。
Try entering the name of a JavaScript class, like Number
, add a dot and press tab
.
尝试输入JavaScript类的名称,例如Number
,添加一个点并按tab
。
The REPL will print all the properties and methods you can access on that class:
REPL将打印您可以在该类上访问的所有属性和方法:
You can inspect the globals you have access to by typing global.
and pressing tab
:
您可以通过键入global.
来检查您可以访问的全局变量global.
然后按tab
:
If after some code you type _
, that is going to print the result of the last operation.
如果在某些代码后键入_
,则将打印最后一个操作的结果。
The REPL has some special commands, all starting with a dot .
. They are
REPL有一些特殊的命令,所有命令都以点开头.
。 他们是
.help
: shows the dot commands help
.help
:显示点命令帮助
.editor
: enables editor more, to write multiline JavaScript code with ease. Once you are in this mode, enter ctrl-D to run the code you wrote.
.editor
:使编辑者更容易编写多行JavaScript代码。 进入此模式后,输入ctrl-D运行您编写的代码。
.break
: when inputting a multi-line expression, entering the .break command will abort further input. Same as pressing ctrl-C.
.break
:输入多行表达式时,输入.break命令将中止进一步的输入。 与按Ctrl-C相同。
.clear
: resets the REPL context to an empty object and clears any multi-line expression currently being input.
.clear
:将REPL上下文重置为空对象,并清除当前正在输入的任何多行表达式。
.load
: loads a JavaScript file, relative to the current working directory
.load
:加载相对于当前工作目录JavaScript文件
.save
: saves all you entered in the REPL session to a file (specify the filename)
.save
:将您在REPL会话中输入的所有内容保存到文件中(指定文件名)
.exit
: exists the repl (same as pressing ctrl-C two times)
.exit
:存在.exit
(与按两次Ctrl-C相同)
The REPL knows when you are typing a multi-line statement without the need to invoke .editor
.
REPL知道何时键入多行语句,而无需调用.editor
。
For example if you start typing an iteration like this:
例如,如果您开始输入这样的迭代:
[1, 2, 3].forEach(num =>; {
and you press enter
, the REPL will go to a new line that starts with 3 dots, indicating you can now continue to work on that block.
然后按enter
键,REPL将转到以3个点开头的新行,表示您现在可以继续在该块上工作。
... console.log(num)... })
If you type .break
at the end of a line, the multiline mode will stop and the statement will not be executed.
如果在一行的末尾键入.break
,则多行模式将停止并且该语句将不会执行。
How to accept arguments in a Node.js program passed from the command line
如何在从命令行传递的Node.js程序中接受参数
You can pass any number of arguments when invoking a Node.js application using:
调用Node.js应用程序时,可以使用以下任意数量的参数:
node app.js
Arguments can be standalone or have a key and a value.
参数可以是独立的,也可以具有键和值。
For example:
例如:
node app.js flavio
or
要么
node app.js name=flavio
This changes how you will retrieve this value in the Node.js code.
这将改变您在Node.js代码中检索此值的方式。
The way you retrieve it is using the process
object built into Node.js.
检索它的方式是使用Node.js中内置的process
对象。
It exposes an argv
property, which is an array that contains all the command line invocation arguments.
它公开了一个argv
属性,该属性是一个包含所有命令行调用参数的数组。
The first argument is the full path of the node
command.
第一个参数是node
命令的完整路径。
The second element is the full path of the file being executed.
第二个元素是正在执行的文件的完整路径。
All the additional arguments are present from the third position going forward.
从第三个位置开始,所有其他参数都存在。
You can iterate over all the arguments (including the node path and the file path) using a loop:
您可以使用循环遍历所有参数(包括节点路径和文件路径):
process.argv.forEach((val, index) => { console.log(`${index}: ${val}`)})
You can get only the additional arguments by creating a new array that excludes the first 2 params:
您可以通过创建一个排除前两个参数的新数组来仅获取其他参数:
const args = process.argv.slice(2)
If you have one argument without an index name, like this:
如果您有一个没有索引名称的参数,如下所示:
node app.js flavio
you can access it using
您可以使用
const args = process.argv.slice(2)args[0]
In this case:
在这种情况下:
node app.js name=flavio
args[0]
is name=flavio
, and you need to parse it. The best way to do so is by using the minimist
library, which helps dealing with arguments:
args[0]
是name=flavio
,您需要对其进行解析。 最好的方法是使用minimist
库 ,该库有助于处理参数:
const args = require('minimist')(process.argv.slice(2))args['name'] //flavio
How to print to the command line console using Node.js, from the basic console.log to more complex scenarios
如何使用Node.js从基本console.log到更复杂的场景打印到命令行控制台
Node.js provides a console
module which provides tons of very useful ways to interact with the command line.
Node.js提供了一个console
模块 ,该模块提供了大量与命令行交互的非常有用的方法。
It is basically the same as the console
object you find in the browser.
它基本上与您在浏览器中找到的console
对象相同。
The most basic and most used method is console.log()
, which prints the string you pass to it to the console.
最基本和最常用的方法是console.log()
,该方法将您传递给控制台的字符串打印出来。
If you pass an object, it will render it as a string.
如果传递对象,它将把它渲染成字符串。
You can pass multiple variables to console.log
, for example:
您可以将多个变量传递给console.log
,例如:
const x = 'x'const y = 'y'console.log(x, y)
and Node.js will print both.
和Node.js将同时打印两者。
We can also format pretty phrases by passing variables and a format specifier.
我们还可以通过传递变量和格式说明符来格式化漂亮的短语。
For example:
例如:
console.log('My %s has %d years', 'cat', 2)
%s
format a variable as a string
%s
将变量格式化为字符串
%d
or %i
format a variable as an integer
%d
或%i
将变量格式化为整数
%f
format a variable as a floating point number
%f
将变量格式化为浮点数
%O
used to print an object representation
%O
用于打印对象表示
Example:
例:
console.log('%O', Number)
console.clear()
clears the console (the behavior might depend on the console used)
console.clear()
清除控制台(其行为可能取决于所使用的控制台)
console.count()
is a handy method.
console.count()
是一种方便的方法。
Take this code:
采取以下代码:
const x = 1const y = 2const z = 3console.count( 'The value of x is ' + x + ' and has been checked .. how many times?')console.count( 'The value of x is ' + x + ' and has been checked .. how many times?')console.count( 'The value of y is ' + y + ' and has been checked .. how many times?')
What happens is that count
will count the number of times a string is printed, and print the count next to it.
发生的情况是, count
将对打印字符串的次数进行计数,并在其旁边打印计数。
You can just count apples and oranges:
您可以只数苹果和橙子:
const oranges = ['orange', 'orange']const apples = ['just one apple']oranges.forEach(fruit => { console.count(fruit)})apples.forEach(fruit => { console.count(fruit)})
There might be cases where it’s useful to print the call stack trace of a function, maybe to answer the question: “How did you reach that part of the code?”
在某些情况下,打印函数的调用堆栈跟踪很有用,也许可以回答以下问题:“您是如何到达代码的那一部分的?”
You can do so using console.trace()
:
您可以使用console.trace()
这样做:
const function2 = () => console.trace()const function1 = () => function2()function1()
This will print the stack trace. This is what’s printed if I try this in the Node REPL:
这将打印堆栈跟踪。 如果我在Node REPL中尝试此操作,将显示以下内容:
Trace at function2 (repl:1:33) at function1 (repl:1:25) at repl:1:1 at ContextifyScript.Script.runInThisContext (vm.js:44:33) at REPLServer.defaultEval (repl.js:239:29) at bound (domain.js:301:14) at REPLServer.runBound [as eval] (domain.js:314:12) at REPLServer.onLine (repl.js:440:10) at emitOne (events.js:120:20) at REPLServer.emit (events.js:210:7)
You can easily calculate how much time a function takes to run, using time()
and timeEnd()
您可以使用time()
和timeEnd()
轻松计算函数运行所需的time()
const doSomething = () => console.log('test')const measureDoingSomething = () => { console.time('doSomething()') //do something, and measure the time it takes doSomething() console.timeEnd('doSomething()')}measureDoingSomething()
As we saw console.log is great for printing messages in the Console. This is what’s called the standard output, or stdout
.
如我们所见,console.log非常适合在控制台中打印消息。 这就是所谓的标准输出或stdout
。
console.error
prints to the stderr
stream.
console.error
打印到stderr
流。
It will not appear in the console, but it will appear in the error log.
它不会出现在控制台中,但是会出现在错误日志中。
You can color the output of your text in the console by using escape sequences. An escape sequence is a set of characters that identifies a color.
您可以使用转义序列在控制台中为文本的输出着色。 转义序列是标识颜色的一组字符。
Example:
例:
console.log('\x1b[33m%s\x1b[0m', 'hi!')
You can try that in the Node REPL, and it will print hi!
in yellow.
您可以在Node REPL中尝试该方法,它会打印成hi!
黄色。
However, this is the low-level way to do this. The simplest way to go about coloring the console output is by using a library. Chalk is such a library, and in addition to coloring it also helps with other styling facilities, like making text bold, italic or underlined.
但是,这是执行此操作的底层方法。 为控制台输出着色的最简单方法是使用库。 Chalk是这样的一个库,除了为它上色外,它还有助于其他样式设置,例如使文本变为粗体,斜体或带下划线。
You install it with npm install chalk
, then you can use it:
您可以使用npm install chalk
安装它,然后可以使用它:
const chalk = require('chalk')console.log(chalk.yellow('hi!'))
Using chalk.yellow
is much more convenient than trying to remember the escape codes, and the code is much more readable.
与尝试记住转义代码相比,使用chalk.yellow
方便得多,并且代码更具可读性。
Check the project link I posted above for more usage examples.
检查我上面发布的项目链接以获取更多用法示例。
Progress is an awesome package to create a progress bar in the console. Install it using npm install progress
.
Progress是一个很棒的软件包,可在控制台中创建进度条。 使用npm install progress
安装它。
This snippet creates a 10-step progress bar, and every 100 ms one step is completed. When the bar completes we clear the interval:
此代码段创建了一个10步进度条,每100毫秒完成一个步。 当小节结束时,我们清除间隔:
const ProgressBar = require('progress')
const bar = new ProgressBar(':bar', { total: 10 })const timer = setInterval(() => { bar.tick() if (bar.complete) { clearInterval(timer) }}, 100)
How to make a Node.js CLI program interactive?
如何使Node.js CLI程序具有交互性?
Node since version 7 provides the readline
module to perform exactly this: get input from a readable stream such as the process.stdin
stream, which during the execution of a Node program is the terminal input, one line at a time.
从版本7开始,Node提供了readline
模块来执行以下操作:从可读流(例如process.stdin
流)获取输入,该流在Node程序执行期间是终端输入,一次只能一行。
const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout})
readline.question(`What's your name?`, (name) => { console.log(`Hi ${name}!`) readline.close()})
This piece of code asks the username, and once the text is entered and the user presses enter, we send a greeting.
这段代码询问用户名,一旦输入了文本并且用户按下Enter键,我们就会发送问候语。
The question()
method shows the first parameter (a question) and waits for the user input. It calls the callback function once enter is pressed.
question()
方法显示第一个参数(问题),并等待用户输入。 一旦按下回车键,它将调用回调函数。
In this callback function, we close the readline interface.
在此回调函数中,我们关闭readline接口。
readline
offers several other methods, and I’ll let you check them out on the package documentation I linked above.
readline
提供了其他几种方法,我将让您在上面链接的软件包文档中进行检查。
If you need to require a password, it’s best to now echo it back, but instead showing a *
symbol.
如果您需要密码,最好现在将其回显,而要显示一个*
符号。
The simplest way is to use the readline-sync package which is very similar in terms of the API and handles this out of the box.
最简单的方法是使用readline-sync 程序包 ,该程序包在API方面非常相似,并且可以立即使用。
A more complete and abstract solution is provided by the Inquirer.js package.
Inquirer.js软件包提供了更完整和抽象的解决方案。
You can install it using npm install inquirer
, and then you can replicate the above code like this:
您可以使用npm install inquirer
,然后可以复制上述代码,如下所示:
const inquirer = require('inquirer')
var questions = [{ type: 'input', name: 'name', message: "What's your name?",}]
inquirer.prompt(questions).then(answers => { console.log(`Hi ${answers['name']}!`)})
Inquirer.js lets you do many things like asking multiple choices, having radio buttons, confirmations, and more.
Inquirer.js允许您执行许多操作,例如询问多项选择,具有单选按钮,确认等。
It’s worth knowing all the alternatives, especially the built-in ones provided by Node.js, but if you plan to take CLI input to the next level, Inquirer.js is an optimal choice.
值得一提的是所有替代方案,尤其是Node.js提供的内置替代方案,但是如果您打算将CLI输入提高到一个新水平,那么Inquirer.js是一个最佳选择。
How to use the module.exports
API to expose data to other files in your application, or to other applications as well
如何使用module.exports
API将数据公开给应用程序中的其他文件或其他应用程序
Node.js has a built-in module system.
Node.js具有内置的模块系统。
A Node.js file can import functionality exposed by other Node.js files.
Node.js文件可以导入其他Node.js文件公开的功能。
When you want to import something you use:
当您要导入内容时,请使用:
const library = require('./library')
to import the functionality exposed in the library.js
file that resides in the current file folder.
导入驻留在当前文件夹中的library.js
文件中提供的功能。
In this file, functionality must be exposed before it can be imported by other files.
在此文件中,必须先公开功能,然后才能由其他文件导入。
Any other object or variable defined in the file by default is private and not exposed to the outer world.
默认情况下,文件中定义的任何其他对象或变量都是私有的,不会暴露给外界。
This is what the module.exports
API offered by the module
system allows us to do.
这就是module
系统提供的module.exports
API允许我们执行的操作。
When you assign an object or a function as a new exports
property, that is the thing that’s being exposed. As such, it can be imported in other parts of your app, or in other apps as well.
当您将对象或函数分配为新的exports
属性时,这就是要公开的内容。 因此,可以将其导入应用程序的其他部分,也可以导入其他应用程序。
You can do so in 2 ways.
您可以通过两种方式进行操作。
The first is to assign an object to module.exports
, which is an object provided out of the box by the module system, and this will make your file export just that