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
- 類型：事件驅動網路