JavaScript >> Javascript 文檔 >  >> Node.js

學習 Node.js:初學者指南

JavaScript 無疑是當今最流行的編程語言之一,這是有充分理由的。它可以輕鬆地在您的瀏覽器、服務器、桌面甚至手機上作為應用程序運行。編寫 JavaScript 的最流行和最簡單的方法之一是使用 Node.js。

學習 Node.js 的資源有很多,但真正為您提供成功編寫 Node 代碼所需的背景、工具和資源的並不多。

因此,我在這裡的目標是為您提供一個我剛開始時希望擁有的指南。我將首先簡要介紹 Node 的實際含義以及它在幕後所做的事情,然後我會給你一些具體的例子,你可以直接在瀏覽器中嘗試,最後我會給你一堆資源來指導您了解一些更有用和實用的示例/概念。

請注意,本指南不會教您如何編碼,而是會指導您了解 Node 運行時和 npm 的基礎知識。

什麼是節點

Node 是一個服務器端跨平台運行時環境,運行在 V8 JavaScript 引擎上,該引擎為 Google 的 Chrome 瀏覽器提供支持。這確實是 Node 的核心,也是真正解析和執行代碼的組件。

V8 引擎通過將 JavaScript 編譯為本機機器碼來實現這一點,這使得它比解釋器快得多。為了進一步加快速度,編譯後的代碼在運行時根據代碼執行配置文件的啟發式動態優化(並重新優化)。這意味著在程序運行時,引擎實際上會跟踪其性能,並根據跟踪的某些因素使代碼更快。

作為一個運行時,Node 的一大重點是使用事件驅動的、非阻塞的 IO 模型來使其輕量和快速。對某些人來說,這種編程模型一開始可能會有點混亂,但它實際上在簡化重 IO 應用程序(如網站)的開發方面做得很好。

這種設計非常適合優化代碼的吞吐量和可擴展性,這也是它如此受歡迎的一個重要原因。例如,有人讓它處理 600,000 個並發 websocket 連接,這太瘋狂了。現在,他必須做一些自定義配置,但這並沒有讓它變得不那麼令人印象深刻。這正是 IBM、Microsoft 和 PayPal 等公司在其 Web 服務中使用 Node 的原因。

現在,Node 甚至不需要太快就能讓它有吸引力。我最喜歡的功能之一實際上是包管理器 npm。很多語言都缺乏像這樣好的包管理器。 npm 是一個命令行工具,可用於初始化模塊、管理依賴項或運行測試等。

公共存儲庫對任何人都是開放的,可以下載和發布代碼。截至撰寫本文時,npm 託管了超過 210,000 個模塊,從網站到命令行工具再到 API 包裝器。

這是我創建的包的示例。您可以看到主頁是 README,其中描述了包的作用以及如何使用它。您還可以快速了解其他信息,例如下載次數、存儲庫位置和使用的軟件許可證。

Node 有什麼用處

除其他外,Node 可能最適合構建需要實時、同步交互的網站和工具。聊天網站/應用程序就是一個很好的例子,因為它們通常非常依賴 IO。非阻塞事件驅動模型允許它同時處理大量請求。

它也非常適合創建 Web API 的前端(通過 REST)。這是因為它針對事件驅動的 IO(我已經提到過)進行了優化 它原生處理 JSON,因此幾乎不需要解析。

什麼節點不是 適合

另一方面,讓我們看看 Node 是什麼不是 擅長。最值得注意的是,它非常不適合執行繁重的計算任務。所以如果你想用 Node 做機器學習之類的事情,你可能不會有最好的體驗。

Node 也還很年輕,因此仍在快速發展中。在過去的幾個月裡,我們從 v0.12.xv5.1.x .因此,如果您需要更穩定的東西,那麼這可能不適合您。

至於異步編程“問題”,我認為這個 Quora 答案的第一部分很好地解釋了它:

雖然異步編程總體上是一件好事,但它確實增加了程序的複雜性。

節點REPL

好的,開始一些代碼。我們將開始非常簡單,只需在 REPL(read-eval-print 循環)中運行一些命令,這只是一個允許您在 shell 中交互式運行 Node 代碼的應用程序。此處編寫的程序是分段執行的,而不是一次全部執行。

我假設您已經熟悉 JavaScript,因此我們將在本文中介紹一些特定於 Node 的內容。

讓我們試試 Node 自帶的一個內置模塊,比如 crypto 模塊。

假設你已經安裝了 Node,運行 node 在你的 shell 中輸入命令,並在提示符處逐行輸入以下代碼:

var crypto = require('crypto');

crypto.createHash('md5').update('hello world').digest('hex');

在 REPL 中輸入最後一行後(或單擊上面的“運行”按鈕),您應該會看到 5eb63bbbe01eeed093cb22bb8f5acdc3 打印到控制台。

crypto 使用 require() 加載模塊 函數,它為您處理代碼的解析和加載。在此處了解有關其工作原理的更多信息。

加載模塊後,您可以使用它的功能,在本例中我們使用 createHash() .由於 REPL 分段執行代碼,它們通常會打印出每一行的返回值,就像您在此處看到的那樣。

您可以使用這樣的 REPL 來快速測試代碼,而無需將其寫入新文件並執行它。它幾乎就像一個通用的沙盒環境。

你的第一個程序

REPL 很有趣,但它們只能讓我們走這麼遠。因此,讓我們繼續編寫我們的第一個真正的 Node 程序。我們暫時不會擔心使用第三方模塊(但別擔心,我們稍後會),所以讓我們先看看有哪些內置代碼可供我們使用。已經為您提供了大量代碼,包括(但不限於):

  • fs :通過標準 POSIX 函數提供的簡單包裝器
  • http :較低級別的 HTTP 服務器和客戶端
  • os :提供一些基本的方法告訴你底層操作系統
  • path :用於處理和轉換文件路徑的實用程序
  • url :用於 URL 解析和解析的實用程序
  • util :標準實用功能,如調試、格式化和檢查

內置的代碼量不在 Python 的水平上,但它會完成這項工作。當您開始使用第三方模塊時,真正的好處就來了。

對於我們的第一個程序,我們將創建一個簡單的實用程序,使用您的 IP 地址確定您的位置(我知道,這有點令人毛骨悚然):

var http = require('http');

var options = {
    hostname: 'ipinfo.io',
    port: 80,
    path: '/json',
    method: 'GET'
};

var req = http.request(options, function(res) {
    var body = '';
    
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
        body += chunk;
    });
    
    res.on('end', function() {
        var json = JSON.parse(body);
        console.log('Your location: ' + json.city + ', ' + json.region);
    });
});

req.end();

複製上面的代碼並將其粘貼到名為“index.js”的文件中。然後,在命令行上,導航到您剛剛創建的文件所在的目錄並運行它:

$ node index.js

您應該會看到“您的位置:[CITY],[REGION]”打印到命令行。打印出來的城市/地區可能離您很近,但並不准確。此外,如果沒有打印任何城市/地區,則表示您的 IP 信息不在數據庫中。

由於此代碼不使用任何第 3 方依賴項,因此不需要 package.json 文件或 node_modules 文件夾,我們將在下一節中詳細解釋。

你的第一個包裹

請注意,在整篇文章中,我交替使用“包”和“模塊”。

對於您使用 Node.js 創建的幾乎每個網站/工具/項目,您還需要圍繞它創建一個模塊。這樣您就可以指定依賴項、測試、腳本、存儲庫等。

一個典型的模塊包含幾個重要的東西:

  • package.json:包含所有模塊信息的 JSON 文件
  • node_modules/:包含所有依賴項的目錄
  • index.js:主要代碼文件
  • README.md:關於模塊的文檔
  • test/:模塊的測試目錄

您可以向模塊添加大量其他內容(例如 .npmignore 文件、docs 目錄或編輯器配置文件),但上面列出的內容是您會看到的一些最常見的內容。

為了展示所有這些是如何工作的,在本節的其餘部分中,我們將在前面的示例的基礎上創建自己的包。

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

我們將使用一些流行的 Node 包來創建一個工具,讓您可以找到任何網站服務器的位置,而不是僅僅根據您的 IP 地址告訴您您的位置。我們稱之為 twenty (看看為什麼)。

初始化包

首先,為您的項目創建並導航到一個新目錄:

$ mkdir twenty
$ cd twenty

然後,使用 npm 初始化項目:

$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (twenty) 
version: (0.0.1) 
description: Locates the city/region of a given URL/IP address
entry point: (index.js) 
test command: 
git repository: 
keywords: 
license: (MIT) 
About to write to /Users/scott/projects/twenty/package.json:

{
  "name": "twenty",
  "version": "0.0.1",
  "description": "Locates the city/region of a given URL/IP address",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Scott Robinson <[email protected]> (http://stackabuse.com)",
  "license": "MIT"
}


Is this ok? (yes) yes

填寫每個提示(從 name: (twenty) 開始 ),或者不輸入任何內容,只需按回車鍵即可使用默認設置。這將創建一個正確配置的 package.json 包含以下 JSON 的文件:

{
  "name": "twenty",
  "version": "0.0.1",
  "description": "Locates the city/region of a given URL/IP address",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Scott Robinson <[email protected]> (http://stackabuse.com)",
  "license": "MIT"
}

此文件是您保存所有項目特定信息的起點。

安裝依賴項

要將依賴項添加到您的項目,您可以使用 npm install 從命令行命令。例如,要添加我們的第一個依賴項,request ,嘗試運行這個:

$ npm install --save request

install 命令將下載最新的 request 從 npm 打包並將其保存在 node_modules 目錄。添加 --save flag 告訴 npm 將包的詳細信息保存在 package.json 的 'dependencies' 部分下:

"dependencies": {
    "request": "2.67.0"
}

現在您可以使用 request 項目代碼中任何位置的模塊。

改進代碼

request 模塊為您提供輕鬆發出各種 HTTP 請求的功能。我們上面展示的 HTTP 示例還不錯,但是 request 使代碼更加緊湊,更易於閱讀。使用 request 的等效代碼 看起來像這樣:

var request = require('request');

request('http://ipinfo.io/json', function(error, response, body) {
    var json = JSON.parse(body);
    console.log('Your location: ' + json.city + ', ' + json.region);
});

如果我們能找到 any 的位置會更有趣 IP 地址,而不僅僅是我們自己的,所以讓我們允許用戶輸入 IP 地址作為命令行參數。像這樣:

$ node index.js 8.8.8.8

為了在我們的程序中訪問這個參數,Node 在全局 process 中提供了它 對象為 process.argv ,這是一個數組。對於我們上面剛剛執行的命令,process.argv 將是 ['node', 'index.js', '8.8.8.8'] .

為了讓事情變得更簡單,我們將使用 yargs 包來幫助我們解析命令行參數。像這樣一個簡單的程序,yargs 不是真的有必要,但我會改進 twenty 在後面的文章中,所以我們不妨現在添加它。

就像 request ,我們將安裝它:

$ npm install --save yargs

修改代碼以使用 yargs 獲取參數(如果沒有給出參數,則默認為我們自己的 IP),我們最終得到:

var request = require('request');
var argv = require('yargs').argv;

var path = 'json';

path = argv._[0] || path;

request('http://ipinfo.io/' + path, function(error, response, body) {
    var json = JSON.parse(body);
    console.log('Server location: ' + json.city + ', ' + json.region);
});

到目前為止,這個工具非常適合命令行使用,但是如果有人想在自己的代碼中使用它作為依賴項怎麼辦?截至目前,代碼尚未導出,因此您無法在命令行以外的任何地方使用它。要告訴 Node 哪些函數/變量可用,我們可以使用 module.exports .

var request = require('request');
var argv = require('yargs').argv;

var findLocation = function(ip, callback) {
    var path;
    if (typeof(ip) === 'function' || !ip) path = 'json';
    else path = ip;
    
    request('http://ipinfo.io/' + path, function(error, response, body) {
        var json = JSON.parse(body);
        callback(null, json.city + ', ' + json.region);
    });
};

module.exports = findLocation;

偉大的!現在任何下載這個包的人都可以在他們的代碼中的任何地方使用它並使用 findLocation() 功能。

但是,您可能已經註意到,現在我們不能再將它用作命令行工具了。我們 想把剩下的舊代碼像這樣放在那裡:

var request = require('request');
var argv = require('yargs').argv;

var findLocation = function(ip, callback) {
    var path;
    if (typeof(ip) === 'function' || !ip) path = 'json';
    else path = ip;
    
    request('http://ipinfo.io/' + path, function(error, response, body) {
        var json = JSON.parse(body);
        callback(null, json.city + ', ' + json.region);
    });
};

var arg = argv._[0] || path;

// This runs every time the file is loaded
findLocation(arg, function(err, location) {
    console.log('Server location: ' + location);
});

module.exports = findLocation;

這會很糟糕,因為任何時候有人 require() s 這個文件使用 findLocation() 函數它會將自己的位置打印到命令行。我們需要一種方法來確定該文件是否被直接調用 使用 node index.js 而不是 require() ,所以如果直接調用它,那麼我們將檢查命令行的參數。這可以通過檢查 require.main 來完成 針對module ,像這樣:if (require.main === module) {...} ,這給我們留下了:

var request = require('request');
var argv = require('yargs').argv;

var findLocation = function(ip, callback) {
    var path;
    if (typeof(ip) === 'function' || !ip) path = 'json';
    else path = ip;
    
    request('http://ipinfo.io/' + path, function(error, response, body) {
        var json = JSON.parse(body);
        callback(null, json.city + ', ' + json.region);
    });
};

if (require.main === module) {
    findLocation(argv._[0], function(err, location) {
        console.log('Server location: ' + location);
    });
}

module.exports = findLocation;

現在我們可以在命令行上使用這段代碼了 作為依賴。

注意:有一種更好的方法來實現 CLI/庫混合,但我們會保持簡單,暫時堅持使用這種方法。有關更多信息,請參閱 Github 上的 20,特別是 bin 目錄和 package.json 設置。

發布你的包

最後,我們希望在 npm 上將其提供給其他人。要使包可用,您需要做的就是在包目錄中運行它:

$ npm publish

系統會提示您輸入用戶名和密碼,然後將代碼推送到註冊表。

請記住,您需要確定您的包的範圍或更改其名稱,因為名稱“二十”已被我使用。

從這裡去哪裡

隨著 Node 的普及,有 整個互聯網的資源。以下是我遇到的一些最受歡迎的書籍和課程,它們會教給您比我在這裡展示的更多的東西:

  • 學習 Node.js 韋斯·博斯(Wes Bos)
  • Node.js Web 開發:使用 Node 10 進行服務器端開發
  • Node.js 設計模式:掌握構建模塊化和可擴展的服務器端 Web 應用程序的最佳實踐
  • 開始 Node.js

或者,如果您想堅持一些較短的教程,這裡有一些來自 Stack Abuse 的教程可能會有所幫助:

  • 避免 Node.js 中的回調地獄
  • 你可能不知道的有用節點包
  • ES6 類
  • 使用 node-cron 在 Node 中運行定期任務

請記住,您學到的大部分內容將來自您自己對語言、工具和包的探索。因此,雖然這樣的文章很適合入門,但請確保您更多地關注編寫代碼而不是閱讀其他人編寫代碼 .經驗勝過一切。

結論

我們只介紹了 Node 和 npm 必須提供的一小部分,因此請查看我上面鏈接的一些資源以了解更多信息。

我怎麼強調都不為過,獲得實際編寫代碼的經驗對你來說是多麼重要。 npm 使瀏覽包和查找它們的存儲庫變得非常容易。所以找一個對你有用或感興趣的包,看看它是如何工作的。

您是 Node 新手嗎?您還想了解哪些其他 Node 主題?請在評論中告訴我們!


Tutorial JavaScript 教程
  1. 無法在mounted() 中調用函數

  2. 如何等待“調整大小”事件的“結束”然後才執行操作?

  3. React:在用戶同意後啟用 Google Analytics

  4. 使用 Python 和 OBS 偽造計算機故障 [實時編碼回顧]

  5. 記錄模板文件描述符

  6. Vue.js 組件介紹

  7. 如何使用 React Context 構建多語言網站 Pt.2

  1. 使用組件為您的應用程序引導數據

  2. 使用 AWS Cognito 進行用戶身份驗證

  3. 將項目添加到 Flatlist,React Native 時遇到問題

  4. JavaScript 中一流函數的 4 個日常用例

  5. 檢測輸入框中的粘貼

  6. 增強 JavaScript 核心對象

  7. ServiceNow:計劃作業,發送審批提醒

  1. 如何使用 NextJS 和 Contentful 構建強大的博客

  2. 如何在 NextJS 中使用 Notion API

  3. 將 Node Express API 轉移到無服務器

  4. 使用 javascript 創建一個停電的詩歌製作器