使用 Visual Studio Code 和 Azure 進行 Node.js 開發
2017 年 1 月 4 日 - Jonathan Carter, @lostintangent
透過 Visual Studio Code 和 Azure,我們正努力簡化和改善構建、除錯和部署 Node.js 應用程式的整體開發者體驗。在 Node Interactive North America 2016 上,我很高興能夠演示我們根據社群反饋最近完成的一些工作。本文旨在為有興趣嘗試或尋求比我演講中更多細節的人們捕捉這一工作流程。
此演示使用了一個由 Scotch.io 建立併發布的一個簡單的 todo 應用程式。它是一個單頁 MEAN 應用程式,因此使用 MongoDB 作為資料庫,Node/Express 用於 REST API/Web 伺服器,Angular.js 1.x 用於前端 UI。使用以下目錄跳轉到感興趣的部分,否則,請繼續閱讀。
先決條件
為了有效地完成此演示,您需要安裝以下軟體
-
Visual Studio Code Insiders build,可在此處下載。您在技術上不需要 Insiders build,但我鼓勵所有人使用它,因為它提供了最新的錯誤修復/功能增強(就像 Chrome Canary build 一樣),並且是 VS Code 團隊使用的相同版本。
-
Azure CLI (>=
v0.1.0b11),可在此處獲取安裝說明:https://github.com/Azure/azure-cli#interactive-install-script。此外,您需要一個 Azure 賬戶,並透過執行az login並按照互動式登入進行操作,使用 Azure CLI 登入。 -
Yarn,可在此處獲取安裝說明:https://yarnpkg.com/en/docs/install。這在技術上不是必需的,但在下面它將用於代替 NPM 客戶端。我推薦它!
此外,由於演示應用程式使用 MongoDB,您需要有一個本地執行的 MongoDB 例項,它偵聽標準埠 27017。實現這一點的最簡單方法是在安裝 Docker 後執行以下命令:docker run -it -p 27017:27017 mongo。
專案設定
首先,我們需要獲取 todo 示例專案,以便開始使用它。為此,請執行以下步驟
-
開啟 Visual Studio Code,按
F1調出命令面板(或者,從View選單中選擇Command Palette...)。 -
鍵入
gitcl查詢Git: Clone命令並按ENTER。
注意:VS Code 命令面板支援“模糊搜尋”,這允許您輸入更少的按鍵來查詢常用命令。
-
在提示符中輸入
https://github.com/scotch-io/node-todo並按ENTER。 -
選擇您要將專案克隆到的資料夾,或建立一個新資料夾(例如,名為
Todos)。此時,VS Code 將克隆儲存庫,並啟動一個以新克隆專案為根的新工作區。
或者,您可以使用 Git CLI 克隆示例儲存庫,但此練習有助於說明 VS Code 透過命令面板提供的一些提高效率的功能。我鼓勵您按 F1 並瀏覽它(以及任何已安裝的擴充套件)提供的各種命令,以確定您還可以做些什麼。
整合終端
由於這是一個 Node.js 專案,我們需要做的第一件事是確保從 NPM 安裝其所有依賴項,因為它們未被簽入 Git 儲存庫。您可以在標準終端中執行此步驟(我推薦 Hyper!),或者,如果您願意,您也可以透過按 CTRL+` 調出 VS Code 整合終端,然後執行 npm install 或 yarn,具體取決於您喜歡的 NPM 客戶端。我喜歡 Yarn,因為它非常快並且提供了一些很棒的工作流程改進,所以我建議如果您還沒有嘗試過,可以去看看。
由於 VS Code 希望自然地融入您現有的工作流程,因此由您決定整合終端何時有用。我發現如果我正在全屏執行 VS Code(特別是新的 Zen 模式!),能夠使用整合終端執行簡單/一次性命令是很棒的。而如果我在做一些更“複雜”的事情,我只會切換到全屏版本的 Hyper。選擇和靈活性是這裡的關鍵。
整合 Git 版本控制
透過 Yarn 安裝應用程式的依賴項會導致生成 yarn.lock 檔案,該檔案提供了一種可預測的方式來在將來重新獲取完全相同的依賴項,而不會在 CI 構建、生產部署或其他開發人員的機器上出現任何意外。
建議將此檔案簽入原始碼控制,為此,您可以輕鬆切換到 VS Code 中的整合 Git 選項卡(帶有 Git 徽標的選項卡),並注意新新增的檔案。您可以輸入提交訊息,然後按 CMD+Enter(或單擊複選標記圖示)以在本地暫存/提交更改。
在幕後,這只是自動化您手動執行的相同 Git CLI 命令,因此,再次由您決定 VS Code 中的整合是否適合您。如果您好奇,可以透過單擊 ... 選單項並選擇 Show Git Output 來調出 Git 輸出視窗。這將顯示 VS Code 代表您執行的所有底層 Git 活動。
專案/程式碼導航
為了熟悉程式碼庫,讓我們玩轉一些 VS Code 提供的導航功能的示例
-
按
CMD+P並輸入.js,這使您可以看到專案中的所有 JavaScript/JSON 檔案,以及它們所在的目錄。同樣,此對話方塊支援與命令面板相同的“模糊搜尋”,因此它非常靈活。
-
選擇
server.js,它是應用程式的啟動指令碼。 -
將滑鼠懸停在第 6 行匯入的
database變數上,以檢視其“型別”。這種在檔案中快速檢查變數/模組/型別的能力非常方便,特別是當我們傾向於花費更多時間閱讀/理解程式碼而不是編寫程式碼時!
-
只需將游標放置在名稱
database的範圍內,您就可以快速檢視同一檔案中對它的所有其他引用,右鍵單擊並選擇 Peek References 允許您檢視專案範圍內的使用情況。
-
除了快速檢查懸停時的變數型別之外,您還可以檢查變數的定義,即使它在另一個檔案中!例如,右鍵單擊第 12 行的
database.localUrl,然後選擇Peek Definition,這使我們能夠快速檢視應用程式如何配置為預設連線到 MongoDB。
雲原生、十二因素應用程式不會像這樣硬編碼配置,因此,最好透過環境變數設定我們的 MongoDB 連線字串,這可以根據部署/環境輕鬆更改。讓我們進行更改!
自動補全
自動補全可以在編寫/探索程式碼時提供巨大的生產力增強,因為它防止您需要不斷引用文件或擔心 API 拼寫錯誤。例如,透過將第 12 行從這裡更改為
mongoose.connect(database.localUrl);
更改為這裡,用環境變數來增強硬編碼的 MongoDB 連線字串
mongoose.connect(process.env.MONGO_URL || database.localUrl);
當鍵入 process. 時,您應該注意到 VS Code 顯示了 Node.js process 全域性 API 的可用成員,而無需您配置任何內容。
這是因為 VS Code 在幕後使用 TypeScript(即使是對於 JavaScript!)來提供型別資訊,然後可用於在您鍵入時通知補全列表。VS Code 能夠檢測到這是一個 Node.js 專案,因此會自動從 NPM 下載 Node.js 的 TypeScript 型別檔案。這使您可以補全其他 Node.js 全域性變數(例如 Buffer 或 setTimeout)以及所有內建模組(例如 fs 和 http)。
除了內建的 Node.js API 之外,這種型別的自動獲取還適用於 2,000 多個第三方庫,例如 React、Underscore 和 Express。例如,為了防止 Mongoose 在無法連線到配置的 MongoDB 資料庫例項時使示例應用程式崩潰,請將以下程式碼行新增到第 13 行
mongoose.connection.on('error', () => {
console.log('DB connection error');
});
當鍵入該內容時,您會注意到您再次獲得了補全,而無需執行任何操作。
您可以透過瀏覽令人驚歎的 DefinitelyTyped 專案來檢視哪些庫支援此自動補全功能,該專案是所有 TypeScript 型別定義的社群驅動來源。
執行應用程式
既然我們已經探索並調整了這個應用程式,現在是時候執行它了。為此,只需按 F5 即可執行應用程式。因為這是我們第一次嘗試執行它,所以系統會要求我們指定要使用的“執行配置”型別
選擇 Node.js v6.3+ (Experimental),它將使用最近新增到 Node.js 中的新 Chrome Debugging Protocol 支援。這樣做會在您的專案中生成一個名為 launch.json 的新檔案,該檔案只是告訴 VS Code 如何啟動和/或附加到您的應用程式以進行除錯。
請注意,它能夠檢測到應用程式的啟動指令碼是 server.js,而且我們不需要更改任何內容即可使除錯正常工作。
此時,再次按 F5 執行應用程式。這將啟動應用程式,並在 VS Code 中啟動 Debug Console 視窗,該視窗顯示我們新執行的應用程式的標準輸出。
此外,此控制檯實際上已附加到我們新執行的應用程式,因此您可以鍵入 JavaScript 表示式,這些表示式將在應用程式中進行評估,並且還包括自動補全!例如,嘗試在控制檯中鍵入 process.env 以檢視我的意思。
如果您開啟瀏覽器,可以導航到 https://:8080 並檢視正在執行的應用程式。在文字框中鍵入一條訊息並新增/刪除一些待辦事項,以瞭解應用程式的工作方式。
除錯
除了能夠執行應用程式並透過整合控制檯與它互動之外,VS Code 還提供了直接在程式碼中設定斷點的功能。例如,按 CTRL+P 調出檔案選擇器,鍵入 route 並選擇 route.js 檔案。
讓我們在第 28 行設定一個斷點,該行表示當我們的應用程式嘗試新增待辦事項時將呼叫的 Express 路由。要設定斷點,只需單擊編輯器中行號左側的裝訂線
注意:除了標準斷點之外,VS Code 還支援條件斷點,這允許您自定義應用程式何時應暫停執行。要使用它們,只需右鍵單擊裝訂線,選擇 Add Conditional Breakpoint...,然後指定您想要斷點所基於的 JavaScript 表示式(例如 foo = "bar")或命中計數。
設定完成後,返回正在執行的應用程式並新增一個待辦事項。這將立即導致應用程式暫停執行,VS Code 將在設定斷點的第 28 行暫停
在暫停的檔案中,我們可以將滑鼠懸停在表示式上以檢視其當前值,檢查本地變數/監視和呼叫堆疊,並使用頂部的除錯工具欄逐步執行。您期望從 IDE 獲得的所有功能,但在一個輕量級的文字編輯器中。再次按 F5 繼續執行應用程式。
全棧除錯
如前所述,這是一個 MEAN 應用程式,這意味著它的前端和後端都使用 JavaScript 編寫。因此,雖然我們目前正在除錯後端 Node/Express 程式碼,但在某些時候,我們可能需要除錯前端/Angular 程式碼。幸運的是,VS Code 擁有一個龐大的擴充套件生態系統,這些擴充套件易於安裝,包括整合的 Chrome 除錯。
為了演示這一點,切換到擴充套件選項卡並在搜尋框中鍵入 chrome
選擇名為 Debugger for Chrome 的擴充套件並單擊 Install 按鈕。完成此操作後,您需要重新載入 VS Code 以啟用擴充套件。它將在重啟期間保留您的工作區,因此無需擔心丟失任何狀態。
按 CTRL+P,輸入/選擇 launch.json 並將該檔案的內容替換為以下內容
{
"version": "0.2.0",
"compounds": [
{
"name": "Full-Stack",
"configurations": ["Node", "Chrome"]
}
],
"configurations": [
{
"name": "Chrome",
"type": "chrome",
"request": "launch",
"url": "https://:8080",
"port": 9222,
"userDataDir": "${workspaceFolder}/.vscode/chrome",
"webRoot": "${workspaceFolder}/public"
},
{
"name": "Node",
"type": "node2",
"request": "launch",
"program": "${workspaceFolder}/server.js",
"cwd": "${workspaceFolder}"
}
]
}
此更改執行兩項操作
-
新增一個用於 Chrome 的新執行配置,這將允許我們除錯前端 JavaScript 程式碼。您可以將滑鼠懸停在指定的任何設定上以檢視有關其功能的文件。太棒了!
-
新增一個“複合”執行配置,這將允許我們同時除錯前端和後端程式碼!複合配置概念非常強大,我們稍後將討論!
要檢視實際操作,請切換到 VS Code 中的除錯選項卡,將選定的配置更改為“Full-Stack”(我們稱之為複合配置的名稱,您可以將其命名為任何您想要的名稱),然後按 F5 執行它。
這將啟動 Node.js 應用程式(如除錯控制檯輸出中所示),以及 Chrome,它配置為導航到 https://:8080 處的 Node.js 應用程式。
按 CTRL+P 並輸入/選擇 todos.js,這是應用程式前端的主要 Angular 控制器。在第 11 行設定一個斷點,這是建立新待辦事項的入口點。
返回正在執行的應用程式,新增一個新的待辦事項,您會注意到 VS Code 現在已在 Angular 程式碼中暫停執行
就像 Node.js 除錯一樣,您可以將滑鼠懸停在表示式上,檢視本地變數/監視,在控制檯中評估表示式等。但是,現在需要考慮兩件很酷的事情
-
Call Stack窗格顯示兩個不同的堆疊:Node和Chrome,並指示當前暫停的是哪個。 -
您可以在前端和後端程式碼之間逐步執行!要測試此功能,只需按
F5,它將執行執行並命中我們之前在 Express 路由中設定的斷點。
透過此設定,我們現在可以直接在 VS Code 中有效地除錯前端、後端或全棧 JavaScript 程式碼。更進一步,複合偵錯程式概念不僅限於兩個目標程序,也不僅限於 JavaScript,因此如果您正在處理一個微服務應用程式,它可能是多語言的,您可以使用我們上面使用的完全相同的工作流程,前提是您安裝了必要的擴充套件(例如 Go、Ruby、PHP)。
將應用程式 Docker 化
說到微服務,讓我們看看 VS Code 為 Docker 開發提供的體驗。許多 Node.js 開發人員正在使用 Docker 為開發、CI 和生產環境提供可移植的應用程式部署。儘管如此,我們聽到了很多反饋,雖然 Docker 的好處非常高,但入門的學習曲線和成本也可能相當高。VS Code 提供了一個擴充套件,試圖幫助簡化一些入門工作!
切換回擴充套件選項卡,搜尋 docker 並選擇 Microsoft Docker 擴充套件。安裝它,然後重新載入 VS Code,就像我們上面為 Chrome 擴充套件所做的那樣。
此擴充套件包括許多內容,其中之一是用於為現有專案生成 Dockerfile 和 docker-compose.yml 檔案的簡單命令。要檢視實際操作,請按 F1(調出命令面板)並鍵入 docker 以顯示 Docker 擴充套件提供的所有命令
選擇 Docker: Add docker files to workspace 命令,選擇 Node.js 作為應用程式平臺,並指定應用程式公開埠 8080。這將生成一個完整的 Dockerfile 和 Docker compose 檔案,您可以立即開始使用。
Docker 擴充套件還為您的 Dockerfiles 和 docker-compose.yml 檔案提供自動補全功能,這使得編寫 Docker 資產變得更加簡單。例如,開啟 Dockerfile 並將第 2 行從
FROM node:latest
更改為
FROM mhart
將游標放在 mhart 中的 t 之後,按 CTRL+Space 檢視 mhart 在 DockerHub 上釋出的所有映象儲存庫。
選擇 mhart/alpine-node,這是一個非常高效和小型的 Linux 發行版,提供了此應用程式所需的一切,沒有任何額外的臃腫(Alpine Linux 非常適合 Docker!)。較小的映象通常更好,因為您希望應用程式構建和部署儘可能快,這使得分發/擴充套件等變得快速。
現在我們有了 Dockerfile,我們需要構建實際的 Docker 映象。同樣,我們可以使用 Docker 擴充套件安裝的命令,方法是按 F1 並輸入 dockerb(使用“模糊搜尋”)。選擇 Docker: Build Image 命令,選擇我們剛剛生成/編輯的 /Dockerfile,然後為映象提供一個包含您的 DockerHub 使用者名稱的標籤(例如 lostintangent/node)。按 <ENTER>,這將啟動整合終端視窗並顯示正在構建的 Docker 映象的輸出。
請注意,該命令只是為您自動化了執行 docker build 的過程,這是您可以選擇使用或直接使用 Docker CLI 的另一個提高效率的示例。哪種方式最適合您!
此時,為了使此映象易於獲取以進行部署,我們只需要將其推送到 DockerHub。為此,調出命令面板,輸入 dockerpush 並選擇 Docker: Push 命令。選擇您剛剛構建的映象標籤(例如 lostintangent/node)並按 <ENTER>。這將自動化呼叫 docker push 並將在整合終端中顯示輸出。
部署應用程式
現在我們的應用程式已經 Docker 化並推送到 DockerHub,我們需要將其實際部署到雲端,以便向世界展示。為此,我們將使用 Azure App Service,它是 Azure 的 PaaS 產品,最近添加了兩個與 Node.js 開發人員相關的新功能
-
支援基於 Linux 的 VM,這減少了使用本機 Node 模組或其他可能不支援 Windows 和/或行為不同的工具構建的應用程式的不相容性。
-
支援基於 Docker 的部署,這允許您簡單地指定 Docker 映象的名稱,並允許 App Service 自動拉取、部署和擴充套件映象。
首先,開啟終端,我們將使用新的 Azure CLI 2.0 來管理您的 Azure 賬戶並預配執行 todo 應用程式所需的基礎設施。使用 az login 命令從 CLI 登入到您的賬戶後(如先決條件中所述),執行以下步驟以預配 App Service 例項並部署 todo 應用程式容器
-
建立一個資源組,您可以將其視為幫助組織 Azure 資源的“名稱空間”或“目錄”。
-n標誌是組的名稱,可以指定為您想要的任何內容。az group create -n nina-demo -l westus注意:
-l標誌指示資源組的位置。在預覽期間,App Service on Linux 支援僅在選定區域可用,因此如果您不在美國西部,並且想要檢查哪些其他區域可用,只需從 CLI 執行az appservice list-locations --linux-workers-enabled即可檢視您的資料中心選項。 -
建立 App Service 計劃,該計劃將管理建立和擴充套件部署應用程式的底層 VM。同樣,為 name 標誌指定您想要的任何值,但請確保
-g標誌引用您在上面為資源組指定的名稱。az appservice plan create -n nina-demo-plan -g nina-demo --is-linux注意:
--is-linux標誌是關鍵,因為它指示您需要基於 Linux 的 VM。沒有它,CLI 將預配基於 Windows 的 VM。 -
建立 App Service Web 應用程式,它表示將在我們剛剛建立的計劃和資源組中執行的 todo 應用程式。您可以粗略地將 Web 應用程式視為與程序或容器同義,將計劃視為它們正在執行的 VM/容器主機。
az appservice web create -n nina-demo-app -p nina-demo-plan -g nina-demo -
配置 Web 應用程式以使用我們的 Docker 映象,確保將
-c標誌設定為您的 DockerHub 賬戶/映象名稱az appservice web config container update -n nina-demo-app -g nina-demo -c lostintangent/node -
啟動應用程式以檢視剛剛部署的容器,該容器將在
*.azurewebsites.netURL 上可用az appservice web browse -n nina-demo-app -g nina-demo
注意:這可能需要一分鐘才能首次載入您的應用程式,因為 App Service 必須從 DockerHub 拉取 Docker 映象,然後才能啟動它。
耶!我們剛剛部署了應用程式。但是,旋轉圖標表示應用程式無法連線到資料庫,這是有道理的,因為我們在開發期間使用的是本地 MongoDB 例項,這顯然無法從 Azure 資料中心訪問。幸運的是,由於我們更新了應用程式以透過環境變數接受連線字串,我們只需要啟動一個 MongoDB 伺服器並重新配置 App Service 例項以引用它。
使用 DocumentDB
雖然我們可以設定一個 MongoDB 伺服器或副本集,並自己管理該基礎設施,但 Azure 提供了另一種名為 DocumentDB 的解決方案。DocumentDB 是一個完全託管、可進行異地複製、高效能的 NoSQL 資料庫,提供 MongoDB 相容層。這意味著您可以將現有的 MEAN 應用程式指向它,而無需更改任何內容,只需更改連線字串即可!讓我們看看如何使用它,這次使用 Azure 門戶,而不是 CLI。
- 轉到 portal.azure.com 並登入到您在 CLI 中使用的同一個賬戶。
- 按
N鍵建立新的 Azure 資源,然後選擇Databases,然後選擇NoSQL (DocumentDB)
- 為您想要的例項命名,但將其
NoSQL API配置為使用MongoDB,並將其Resource Group配置為Use Existing並選擇您為 App Service 例項建立的相同資源組。
- 單擊
Create按鈕,等待 DB 預配。
完全建立 DocumentDB 例項需要幾分鐘時間,因此請等到您在門戶右上角看到部署成功通知。完成後,導航到左側導航欄上的 All Resources 選項卡(帶有綠色網格圖示的選單項),然後選擇您建立的 DocumentDB 資源
單擊 Settings 部分下的 Connection String 選單項,然後單擊 Connection String 欄位旁邊的複製按鈕,將 MongoDB 連線字串複製到剪貼簿。
返回門戶中的 All Resources 頁面,導航到您之前建立的 App Service 例項。單擊 Settings 部分下的 Application Settings 選單項,然後在 App settings 部分下新增一個新條目,其鍵為 MONGO_URL,其值為我們之前複製的 DocumentDB 連線字串。
單擊 Save 按鈕,然後返回瀏覽器並重新整理它。嘗試新增和刪除待辦事項,以證明應用程式現在可以工作,而無需更改任何內容!我們只是將環境變數設定為我們建立的 DocumentDB 例項,該例項完全模擬 MongoDB 資料庫。
需要時,我們可以切換回 DocumentDB 例項,並根據需要擴充套件(或縮小)MongoDB 例項所需的保留吞吐量,並受益於增加的流量,而無需手動管理任何基礎設施。
此外,DocumentDB 會自動為您索引每個文件和屬性,因此您無需擔心分析緩慢的查詢和/或手動微調索引。只需根據需要預配和擴充套件,讓 DocumentDB 處理其餘部分!
清理
為了確保您不會為未使用的 Azure 資源付費,只需從終端執行以下命令即可刪除我們剛剛預配的所有資源
az group delete -n nina-demo
這需要幾分鐘才能完成,但完成後,您的 Azure 賬戶將處於與我們開始之前相同的狀態。這種將 Azure 資源作為一個單元進行組織、部署和刪除的能力是資源組的首要好處之一,因此將來,如果您使用 Azure,我建議將您期望具有相同生命週期的資源分組在一起。
結論
希望此演示說明了 Visual Studio Code 正在努力改進整體 Node.js 開發體驗的一些方式。在支援全棧和微服務的除錯、提供導航和自動補全而無需任何進一步配置的豐富創作體驗,以及像 Docker 這樣的擴充套件的龐大生態系統之間,我們可以增強您對其他應用程式型別和實踐的反饋迴圈,我們很高興能夠繼續發展輕量級編輯器中的生產力。
此外,在 Azure CLI、App Service 和 DocumentDB 之間,我們正努力為 Node.js/MEAN 應用程式提供一個富有成效且低管理的雲堆疊,該堆疊可以根據需要擴充套件,而不會引入額外的基礎設施複雜性。
除了簡單地提供 NINA 2016 演示的演練之外,我們希望使用此演示繼續迭代 VS Code 和 Azure 中的整體 Node.js 體驗,以便我們可以使其更簡單、更靈活。如果您對我們如何改進有任何問題或反饋,請隨時在此 repo 上提交問題或給我傳送電子郵件。謝謝!