總算來到 Infrastructure 的部份了,前面用了 10 篇,也正好是 1/3 的篇幅,講解一些 General 的概念及架構,現在我要再用另外 1/3 的篇幅來告訴你我們的 Boilerplate 精華之處,其實這也是我撰寫這一系列文章的主要目的。
一個真正要上線的 Web App 要顧慮的事情真的很多,先從使用者的觀點來看:
再從開發者的角度來看:
除了上列這些功能性層面的東西,身為一個工程師,你還必須要掌控程式碼的品質,要有彈性、容易維護、容易測試、容易擴充,那些覺得寫網站很簡單的人真的是要嘛腦袋有洞,要嘛就是腦袋裝屎啦!
真的不得不說 Github 上面翻到的大多數 Boilerplate 根本都是在玩扮家家酒,Boilerplate 是用來節省開發時間的,是用來讓你開心工作、輕鬆維護的,結果這些來路不明的 Boilerplate 給出來的是什麼東西呢?Server 還真的是夠陽春的,只用來 Host 靜態檔案;表單連個 ReCaptcha 都沒有,隨便寫個 Bot 就打趴了;支援多國語系的更是少得可憐。咱們是要實戰,不是交作業啊!
對不起我抱怨完了。
所以我們的 Boilerplate 其實投入了大量的時間在實作上述的各種 Infrastructure
,這些才是真實世界的 App 需要在乎的細節不是嗎?我已經幫各位讀者顧及全局,找出我認為是最佳解的架構及寫法,後續文章將會講解我是如何實作這些 Infrastructure,以及這樣的寫法有什麼樣的好處。如果讀者們不想浪費時間實作這些 Infrastructure,可以直接拿我們的 Boilerplate 來使用,如果你正在實作自己的 Boilerplate,也歡迎改良我的作法。
今天是 Infrastructure 的 Introduction,所以先來給各位讀者一顆震撼彈吧!今後我們會一直提到 Isomorphic
這個術語,不用急著開 Google 翻譯了,因為翻了你也是看不懂的,請直接閱讀 Airbnb 的這篇精采教學文:Isomorphic JavaScript: The Future of Web Apps。
如果各位看完了還是「不明覺厲」,我會用我的理解來詮釋一遍。
Node 的世界前後端都是撰寫 JavaScript,因此讓我們可以衍伸出前後端共用程式碼的技巧,這其實已經反映在我們 Boilerplate 的檔案結構的 client
、common
、server
三個資料夾上了。Frontend 透過 Webpack 打包時,是取出 client
及 common
兩個資料夾中的程式碼;Backend 的 Server 執行時,是跑 server
及 common
兩個資料夾中的程式碼。所謂的共用並不全然是讓一樣的程式碼表現一樣的行為,而是一整包 common 程式各自表述,當程式碼跑在 Client 時,要表現出 A 行為,當程式碼跑在 Server 時,又要表現出 B 行為,實務上的程式其實會長成這樣:
if (process.env.BROWSER) {
// client-side, do A
document.getElementById(...);
} else {
// server-side, do B
}
上圖擷取自 Airbnb 的教學文,我覺得它有助於視覺化 Isomorphic App 的概念,撰寫 Isomorphic 程式時隨時想想這張圖,可以有效地幫助思考。
有的人可能除了聽過 Isomorphic,還聽過 Universal
,其實兩者是不同的東西,但我認為沒有必要在此系列文章裡鑽這種牛角尖,你只要知道他們是不同的東西即可,但我在文章裡的用語為了方便還是會統稱為 Isomorphic
。想要深入了解的讀者可以參考 Isomorphism vs Universal JavaScript 一文。