Node.js

Node.js 是跨平台、开源的 JavaScript 运行环境，可在 Windows、Linux、macOS 等操作系统上运行。Node.js 由 OpenJS Foundation （原为 Node.js Foundation，已与 JS Foundation 合并）持有和维护，亦为 Linux 基金会的项目。Node.js 采用 Google 开发的 V8 执行程式码，使用事件驱动和异步输入输出模型等技术来提高效能，可优化应用程序的传输量和规模。这些技术通常用于资料密集的即时应用程序。

Node.js 大部分基本模组都用 JavaScript 语言编写。在 Node.js 出现之前，JavaScript 通常作为用户端程式设计语言使用，以JavaScript 写出的程式常在用户的浏览器上执行。Node.js 的出现使 JavaScript 也能用于服务器端编程。Node.js 含有一系列内置模组，使得程式可以脱离 Apache HTTP Server 或 IIS，作为独立服务器执行。

目前，Node.js 已被IBM、Microsoft、Yahoo!、Walmart、Groupon、SAP、LinkedIn、Rakuten、PayPal、Voxer、GoDaddy等企业采用。

## 概览

Node.js可透过JavaScript和一系列模块来编写服务器端应用和网络相关的应用。核心模组包括文件系统I/O、网络（HTTP、TCP、UDP、DNS、TLS/SSL等）、二进制数据流、加密算法、数据流等等。Node模块的API形式简单，降低了编程的复杂度。

使用框架可以加速开发。常用的框架有Express.js、Socket.IO和Connect等。Node.js的程序可以在Microsoft Windows、Linux、Unix、Mac OS X等服务器上运行。Node.js也可以使用CoffeeScript（一种旨在简化JavaScript的替代语言，其代码可按照一定规则转化为合法的JavaScript代码）、TypeScript（微软开发的强化了数据类型的JavaScript变体）、Dart语言，以及其他能够编译成JavaScript的语言编程。

Node.js主要用于编写像Web服务器一样的网络应用，这和PHP和Python是类似的。但是Node.js与其他语言最大的不同之处在于，PHP等语言是阻塞的（只有前一条命令执行完毕才会执行后面的命令），而Node.js是非阻塞的（多条命令可以同时被运行，通过回调函数得知命令已结束运行）。

Node.js是事件驱动的。开发者可以在不使用线程的情况下开发出一个能够承载高并发的服务器。其他服务器端语言难以开发高并发应用，而且即使开发出来，性能也不尽如人意。Node.js正是在这个前提下被创造出来。Node.js把JavaScript的易学易用和Unix网络编程的强大结合起来。

Node.js使用Google V8 JavaScript引擎，因为：

- V8是基于BSD许可证的开源软件
- V8速度非常快

Node.js已经有数十万模组，它们可以透过一个名为npm的管理器免费下载。Node.js开发社区主要有两个邮件列表、一个在freenode的名为#node.js的IRC频道。社区集中在NodeConf。

## 历史

<image>

Node.js于2009年写成，原始作者是美国软件工程师瑞安·达尔（Ryan Dahl）。Node.js结合了Google的V8、事件驱动模式和低级I/O接口，其设计灵感源自Flickr的一款上传进度栏：在上传过程中，浏览器并不清楚有多少文件已经发送到服务器，除非向服务器进行查询，于是达尔想出了一个更简便的方法。Node.js的开发和维护工作由达尔本人主持，而他所在的Joyent公司也提供了赞助。2009年11月8日，达尔在欧洲JSConf大会上展示了Node.js项目，并受到了观众赞赏。在演讲中，达尔针对Apache HTTP Server和顺序编程方式提出了批评，认为Apache处理大量并发连接（10,000甚至更多）的可能性有限，而且顺序编程方式在多连接情况下会造成阻塞，或者消耗更多资源；而Node.js提供了基于事件驱动和非阻塞的接口，可用于编写高并发状态下的程序，而且JavaScript的匿名函数、闭包、回调函数等特性就是为事件驱动而设计的。

2010年1月，一款名为“npm”的软件包管理系统诞生。npm使程序员能够更方便地发布和分享Node.js类库及源代码，而且简化了类库安装、升级与卸载的过程。Node.js最初只支持Linux和Mac OS X操作系统。2011年6月，微软和Joyent共同合作，把Node.js移植到了Windows系统上面，并且在7月发布了第一个正式支持Windows系统的版本。

2012年1月，达尔离开了Node.js项目，开发工作由他的同事以及npm创始人艾萨克·施吕特（Isaac Schlueter）继续主持。2014年2月，蒂莫西·费里斯（Timothy J. Fontaine）接任项目主管。

由于长期对Joyent的管理感到不满，Node.js核心开发者Fedor Indutny在2014年12月制作了分支版本，并起名“io.js”。与Node.js相对的是，io.js采用开放管理模式进行管理，并计划始终采用最新版的V8引擎。为了在用户、厂商和开发者之间取得平衡，Node.js基金会于2015年初成立。基金会得到了IBM、Intel、微软、Joyent等公司的支持。6月，Node.js和io.js开发者社区共同决定合并到Node.js基金会之下。同年9月，Node 4.0发布，Node.js和io.js正式合并。4.0版引入了ES6的语言特性和“长期支持版本”的发布周期。到了2016年，io.js宣布不再发布新版本，并建议开发者换回Node.js。

## 程式范例

用Node.js撰写的HTTP Server版hello world范例：

```javascript
const http = require('http');

http.createServer((request, response) => {
  response.writeHead(200, { 'Content-Type': 'text/plain' });
  response.end('Hello World!');
}).listen(8000);

console.log('Server running at http://127.0.0.1:8000/');
```

另一个简单的TCP服务器范例，监听（Listening）端口7000并输出（echo）之前输入的讯息：

```javascript
const net = require('net');

net.createServer(stream => {
  stream.write('hello\r\n');
  stream.on('end', () => stream.end('goodbye\r\n'));
  stream.pipe(stream);
}).listen(7000);
```

## 技术

### 执行绪

Node.js以单执行绪执行，使用非阻塞I/O呼叫，这样既可以支援数以万计的并行连线，又不会因多执行绪本身的特点而带来麻烦。众多请求只使用单执行绪的设计意味着可以用于建立高并行应用程序。Node.js应用程序的设计目标是任何需要操作I/O的函式都使用回呼函式。

这种设计的缺点是，如果不使用cluster、StrongLoop Process Manager或pm2等模组，Node.js就难以处理多核或多执行绪等情况。

### V8

V8是为Google Chrome设计的JavaScript运行引擎，Google于2008年将其开源。V8用C++写成，它将JavaScript源代码编译成本地机器码而不是解释执行。

Node.js用libuv来处理异步事件，而V8提供了JavaScript的实时运行环境。libuv是一个网络和文件系统功能的抽象层，既可以用于Windows又可以用于符合POSIX标准的系统，例如Linux、OS X和Unix。

Node.js的核心功能被包含进一个JavaScript库，并通过C++将各部分与操作系统进行联系。

### npm

npm是Node.js附带的包管理器。npm是一个命令行工具，用于从NPM Registry中下载、安装Node.js程序，同时解决依赖问题。npm提高了开发的速度，因为它能够负责第三方Node.js程序的安装与管理。

### 统一API

Node.js将浏览器、数据（例如MongoDB或CouchDB）等组合到一起，通过JSON提供一个统一的接口。由于前端框架和一些基本的后端开发技术（如MVC、MVP、MVVM等）变得流行，Node.js也支持客户端和服务器端重新利用相同的模型和接口。

### 事件循环

Node.js将其注册到操作系统中，这样可以及时注意到新连接的产生。当新连接产生时，操作系统会产生一个回调。在Node.js运行时内部，每个连接都被分配一个小型的堆。与其他服务器程序不同的是，Node.js不使用进程或线程处理连接，而是采用事件循环来处理并发连接。而且Node.js的事件循环不需要手动调用。在回调函数定义之后，服务器进入事件循环。当回调函数均被执行完毕之后，Node.js结束事件循环。

## 开发工具

桌面IDE

- Atom（免费、开源软件）
- Brackets（免费、开源软件）
- Sublime Text（商业软件）
- JetBrains IntelliJ IDEA（商业软件）
- JetBrains WebStorm（商业软件）
- Microsoft Visual Studio with Node.js Tools for Visual Studio（商业软件）
- Microsoft Visual Studio with TypeScript（商业软件）
- Nodeclipse Enide Studio（免费、开源软件、在Eclipse基础上开发）
- NoFlo –与GNOME API集成的流式开发环境
- Visual Studio Code（免费、开源软件）

在线编辑器

- Koding
- Codenvy IDE
- Cloud9 IDE
- Codiad

运行时和调试器

- Microsoft Visual Studio（商业）with Node.js Tools for Visual Studio（免费）
- Microsoft WebMatrix（免费、闭源软件）
- Visual Studio Code

框架

- 服务器端框架：Express.js, Socket.IO, Koa.js, Hapi.js, Total.js
- MVC框架：Meteor, Derby, Sails, Mean, MeanJS, Tower.js, Nombo, Geddy, Compound, Yahoo! Mojito

## 替代品

以下是兼容Node.js代码的运行时。

### Bun

Bun是用Zig语言编写的JavaScript运行时，支持JavaScript和TypeScript项目的测试、编译和运行。首个对外版本于2022年7月发布。

## 参见

- Rhino (JavaScript引擎)
- npm：广泛使用的Node.js安装包管理器
- MEAN
- JSAN（JavaScript Archive Network），一个不太常用的JavaScript安装包管理器

## 外部链接

- https://nodejs.org
- Node.js源代码
- Also Read -Best Magento 2 Extensions

## 基本资料

- 作者：瑞安·达尔
- 开发者：OpenJS Foundation
- 发行日期：2009年5月28日
- 编程语言：C、C++、JavaScript
- 操作系统：macOS, Linux, Windows, FreeBSD, OpenBSD
- 类型：事件驱动网络