[譯]2017年,一個Node開發者的好習慣

原文鏈接:Habits of a Happy Node Hacker 2017

從我們之前發布的 Happy Node Hackers 算起,已經差不多一年了。儘管時間很短,但卻已發生了很多變化,一些強大的新工具已經發布了。 Node.js生態系統持續迭代,已出現了更新的最佳實踐。

以下是2017年Node開發者的8個新習慣。它們專門針對應用開發者,而不是模塊作者,因為他們有不同的目標和約束:

1.鎖定你的依賴樹

在如今的許多Node應用程序中,你的代碼通常只是冰山一角。即便是一個非常小的應用,也可能有數千行的Javascript代碼隱藏在node_modules里。如果在package.json中,你的應用指定了確切的依賴項,而這些庫可能並不存在。因為隨著時間推移,你每次install都可能獲得不同的代碼,從而導致一些不可預期的潛在bug。

在過去的一年中,Facebook 發布了一種新的包管理器Yarn。它可以讓你使用龐大的npm庫中的將近50萬個模塊,並生成一個鎖文件(lockfile)來保存你的依賴樹中每個模塊的精確版本。這意味我們在每次發布應用時都將下載完全相同的代碼。

不過,npm也發布一個帶鎖文件(lockfile)的新版本。確實,npm現在更快了。這意味著無論你選擇哪種包管理器,你都將感受安裝時的巨大改進,並且在生產中也會出現更少的錯誤。

使用Yarn時,安裝它並運行在你的應用目錄下。它將安裝你的依賴項並生成一個yarn.lock文件,在編譯你的應用時,它會告訴Heroku使用Yarn進行編譯。

使用npm 5時,在本地運行npm install -g npm@latest命令進行升級,運行rm -rf node_modules && npm install命令重新安裝你的應用依賴包。生成的package-lock.json文件會告訴Heroku去使用npm 5來安裝你的模塊。

2.鉤起來

自動化構建中scripts提供很多好用的鉤子。如果你想在編譯你的應用之前運行一些東西,你可以使用preinstall腳本。需要使用grunt, gulp, browserify, 或者 webpack 來構建assets嗎? 在postinstall中完成它吧。

在package.json中:

"scripts":{ "postinstall":"grunt build", "start":"node app.js" }

你也可以使用環境變數去控制這些腳本:

"postinstall": "if $BUILD_ASSETS; then npm run build-assets; fi", "build-assets": "grunt build"

如果你的腳本需要一些外部的支持,可以移到sh之類文件里:

"postinstall": "scripts/postinstall.sh"

3.現代化你的Javascript

隨著Node 8的發布,在ES2015中維護一個複雜的構建系統來編寫我們的應用程序的日子已經過去了。Node現在已經有99%的特性與ES2015規範一起完成了,這意味著你可以使用這些新的特性,例如 模板字元串 或者解構賦值, 而不需要任何的轉換或者構建過程。

const combinations = [ { number: "8.0.0", platform: "linux-x64" }, { number: "8.0.0", platform: "darwin-x64" }, { number: "7.9.0", platform: "linux-x64" }, { number: "7.9.0", platform: "darwin-x64" } ]; for (let { number, platform } of combinations) { console.log(`node-v${number}-${platform}.tar.gz`); }

還有許多這樣的語法糖,總之,這些顯著提高了JavaScript的可讀性,並使代碼更具表達性。

4.保持你的Promises

除了ES2015,Node 8還支持期待已久的async和await關鍵字,而不再是實驗特性。這個特性建立在Promises的基礎之上,允許你編寫看起來像同步代碼的非同步代碼,並且具有相同的錯誤處理語義,使編寫更容易、更容易理解和更安全。

你可能需要重新以下編寫嵌套的回調代碼:

function getPhotos(fn) { getUsers((err, users) => { if (err) return fn(err); getAlbums(users, (err, albums) => { if (err) return fn(err); getPhotosForAlbums(albums, (err, photos) => { if (err) return fn(err); fn(null, photos); }); }); }); }

改變成自上而下而不是由內到外的代碼:

async function getPhotos() { const users = await getUsers(); const albums = await getAlbums(users); return getPhotosForAlbums(albums); }

你可以在任何回調中調用await。如果你有仍然期望回調的函數,Node 8實現了util.promisify,它可以自動將一個用回調風格編寫的函數轉換為一個await可以使用的函數。

5.使用Prettier自動格式化你的代碼

我們都花了太多的時間來格式化代碼,在這裡添加一個空格,在那裡調整注釋,我們自己做的和我們同事做的會有一點不同。關於分號的位置,或者我們是否應該使用分號,就引出了無休止的爭論。Prettier是一個開源工具,它承諾最終消除那些無意義的爭論。你可以以任何你喜歡的樣式編寫代碼,並且使用一個命令,它的格式都是一致的。

這聽起來像是一件小事,但讓你自己從空格中解脫出來,很快就會讓人感到解脫。Prettier是幾個月前才發布的,但它已經被Babel、React、Khan Academy、Bloomberg以及更多的人所接受。

如果你討厭寫分號,讓Prettier幫你添加,或者你的整個團隊可以用--no-semi選項永遠把它們驅逐出去。Prettier支持ES2015和Flow語法,而最近的1.4.0版本也增加了對CSS和TypeScript的支持。

它可以集成到大部分的文本編輯器,但是我們建議將其設置成pre-commit的鉤子或放在package.json的生命周期腳本里:

"scripts": { "prettify": "prettier --write src/**/*.js" }

6. 持續測試

推出一個新功能,卻發現破壞了生產應用程序,這是非常不爽的。如果你很勤奮地為你編寫的代碼編寫測試,那麼你可以避免這種錯誤,但是編寫一個好的測試套件需要花費大量的時間。此外,該功能需要在昨天發布,而這僅僅是第一個版本。為什麼還要編寫那些在下周就要重寫的測試用例?

在像Mocha或Jest這樣的框架中編寫單元測試是確保JavaScript代碼健壯和設計良好的最好方法之一。然而,有許多代碼可能無法判斷應該投入多少時間去測試。測試庫Jest有一個稱為快照測試的特性,它可以幫助你獲得對那些無法測試的代碼的洞察力和可視性。而不是決定提前判斷一個函數調用應有的輸出並且編寫一個測試用例,Jest會將首次運行的結果保存到一個本地文件中,然後用它與下一次運行的結果進行比較,如果有變化,它將會提醒你。

雖然這並不會告訴你你的代碼是否和你寫的時候一樣,但這確實能讓你觀察到你在快速移動和開發新功能時,你正在向你的應用中引入哪些變化。當輸出更改時,你可以使用一個命令快速更新快照,它們將與你的代碼一起被檢入你的git歷史記錄。

it("test /endpoint", async () => { const res = await request(`http://0.0.0.0:5000/endpoint`); const body = await res.json(); const { status, headers } = res; expect({ status, body, headers }).toMatchSnapshot(); });

測試demo

一旦你測試了你的代碼,建立一個好的CI工作流是確保它能被測試的一種方法。為了達到這個目的,我們推出了Heroku CI。它構建在Heroku持續交付工作流程中,你永遠不會等待隊列。點擊這裡查看詳情!

不需要花哨的功能,只想要一個超級簡單的測試運行器嗎? Check out Tap,以滿足你的最低測試需求。

7. 戴上你的 Helmet

針對web應用程序的安全性,可以通過一些簡單而又重要的配置來鎖定你的應用程序去返回正確的HTTP頭部。

在生產環境中,一個基於Exrpess的應用可以通過使用Helmet,可以使你的程序更完美。Helmet是一個快捷的中間件模塊,主要通過HTTP頭來保護你的應用程序。(PS:原文有點啰嗦,這裡概括了一下)

Helmet可以幫助你防止跨站腳本攻擊,防止點擊劫持,等等!只需要幾行就可以將基本的安全性添加到現有的express應用程序中:

const express = require(express);const helmet = require(helmet);const app = express();app.use(helmet());

閱讀更多

8. 請使用HTTPS

通過默認使用私有連接,並使之成為規範,這樣每個人都會更安全。作為web工程師,我們沒有理由不將應用程序中的所有流量都默認為使用HTTPS。

在express應用程序中,你需要做一些事情來確保你的站點是通過https服務的。首先,確保在響應中設置了Strict-Transport-Security請求頭部(通常縮寫為HSTS)。這指示瀏覽器總是通過https發送請求。如果你在使用Helmet,那麼這已經為你做了!

然後,確保將任何http請求重定向到伺服器,通過https連接到相同的url。express-enforce-ssl中間件提供了一種簡便的方法。

const express = require(express);const expressEnforcesSSL = require(express-enforces-ssl);const app = express();app.enable(trust proxy);app.use(expressEnforcesSSL());

此外,你還需要證書機構頒發的TLS證書。但是如果你將應用程序部署到Heroku或者其它專業dyno環境,你將自動得到TLS證書,我們會通過自動化證書管理工具為你的域配置加密,如果你沒有一個自己的域名,我們提供一個通用的子域*.herokuapp.com

你的習慣是什麼?

我試著在我的所有項目中遵從這些習慣。不管你是 node 新人還是服務端 JS 老手,我確定你會為 自己開發一些技巧。我們非常歡迎聽到它們!使用 #node_habits 標籤,分享你的習慣!

Happy hacking!


推薦閱讀:

開發者和用戶之間的世界觀距離有多大?
前端系列教學(入門篇) - 響應式設計(2)
框架基礎:ajax設計方案(三)--- 集成ajax上傳技術 大文件/超大文件前端切割上傳,後端進行重組
PS教程:Web前端必備PS技能,視頻講解

TAG:Nodejs | 前端开发 | npm |