一個外行如何快速融入node專案開發

Alchemist發表於2019-03-04

一個外行如何快速融入node專案開發
nodejs

去年上半年開始接觸了一些JS的後端程式設計,參與了一個基於node(其實是Meteor)的開源專案,有一些知識上的積累,現在迴歸了Java老本行,怕再過段時間就忘了,在這裡記錄一下,好記性不如爛筆頭,說不定以後會有用。node大神可以看來消遣,跟我一樣是外行但是需要寫一些node程式的可以看看經驗。這篇文章裡會包含以下內容:

  1. 背景
  2. 關於Wekan
  3. 關於Meteor
  4. 關於publication&subscription
  5. 關於Jade&Stylus
  6. 關於JS

背景

第一次知道nodejs是在12年實習時,那時只感覺寫出來的程式碼好難看,覺得JS寫服務端效能肯定也不咋滴。直到2016年之前,我對於JS的使用還僅限於在網頁端偶爾用來做一些欄位驗證,甚至連JQuery都不怎麼會用,老忘記各種selector的語法。

16年開始接觸了一些nodejs的框架,忽然好像發現了個新天地,ES6的語法太美妙,nodejs的「單執行緒非同步IO」的設計也可以最大限度地發揮CPU的效能。後來為了提高工作效率,開始在公司推敏捷,於是找到了一個開源的KANBAN(關於KANBAN可以看這裡)工具Wekan,使用一段時間後發現少了兩個很重要的feature:

  1. Wekan設計的理念是像Trello那樣的一個開放的KANBAN平臺,所以預設是開放註冊的,但是有很多使用者會像我這樣把它部署在自己的私服上(像gitlab一樣),所以希望有一個開關,可以控制不開放註冊,而只能邀請註冊。

  2. 在卡片中沒有一個可以check的列表,讓任務的管理者去更細粒度地控制這個任務。

於是去issue和PR裡找,發現好多人都在等待著兩個feature,於是想,等他們搞不如自己搞。於是開始了第一次真正的node專案的開發。之前做過一些基於Koa和Express的開發,和Meteor還是有很大的區別。

關於Wekan

一個外行如何快速融入node專案開發
專案首頁

Wekan是一個開源的KANBAN(看板管理)工具,是一種較簡單(相對於Scrum和XP)的敏捷開發的理念。KANBAN工具比較有名的有Trello等。Wekan和Trello十分相似,具體的可以去查閱Wekan專案的Wiki。Wekan的優勢就是,對於不想在公共平臺上部署自己的專案管理工具的公司,以MIT協議開源的Wekan是一個很好的選擇,如果你也有這方面的需求,不妨試一試Wekan。

Wekan is an open-source kanban board which allows a card-based task and to-do management, similar to tools like WorkFlowy or Trello.
---- Wekan Wiki

從技術上講,Wekan的後端整體和前端的渲染引擎是基於Meteor的,前端的模板和樣式使用了Jade和Stylus,對於這三個東西都是比較陌生的,本文主要講的就是如何快速地融入這種技術棧不熟悉的專案開發中去。

關於Meteor

首先就是去搜尋了一下關於這個框架的文章,這樣可以簡單地建立起來對它的一個感性認識。找到了一些簡單的介紹,和一箇中文的社群,但是剛剛建立,資料也很少。於是果斷開始閱讀官方文件,所幸官方文件十分詳細。

一個外行如何快速融入node專案開發
又一個JS框架

Meteor是一個基於nodejs的全棧開發框架,致力於使開發者快速、高效地構建高響應的富客戶端Web應用。技術棧包括MongoDB、WebSocket、Blaze等。Meteor引入了客戶端DB的概念,使得Meteor開發的應用,可以天然的達到前端的實時響應。

一個外行如何快速融入node專案開發
Meteor應用架構

從上圖中可以看到,服務端通過publication把一部分資料釋出到前端,前端通過subscription可以直接呼叫這些資料。對於前端來說,它只和前端資料庫互動,基本上等於本地互動,所以響應很快,而前端資料庫再通過和後端實時同步資料來達到和後端互動的目的。

像聊天應用這種實時性要求比較高的服務,可以直接從這種架構受益,使用者幾乎感受不到延遲,而且伺服器上的資料更新也會實時同步到訂閱它的客戶端。

安裝

根據官網的介紹,安裝Meteor只需要在Console中執行curl https://install.meteor.com/ | sh,然而,由於網路原因,在中國直接這麼做簡直是折磨人,要等到花兒都謝了(除非你有一個強大的穩定的合法的VPN)。

我的做法是首先把網頁install.meteor.com/的內容儲存到本地,下載其中TARBALL_URL的包,儲存到INSTALL_TMPDIR中的目錄,然後註釋掉檔案中的下載命令(echo "Downloading Meteor distribution"這一行的後面的一坨),然後執行檔案。

Meteor目錄結構

Meteor也遵循「convention over configuration」,它有預設的一套目錄結構,遵循這套規則可以極大地提高開發效率。Meteor專案的檔案載入順序如下:

  1. HTML模板檔案總是比其他檔案先被載入
  2. 以main為名字的檔案總是最後被載入
  3. lib目錄下的檔案隨後被載入
  4. 更深目錄中的檔案隨後被載入
  5. 其他檔案按照字元順序被載入

還有一些特殊目錄:

  1. imports
    這個資料夾中的檔案不會被載入,除非使用import語句映入到其他檔案。
  2. client
    這個檔案中的檔案不會被服務端的程式載入,相當於在程式中使用if (Meteor.isClient) { ... }來執行程式碼。在production環境這個資料夾下的相關檔案會被壓縮。
  3. server
    與client相對應,這裡的程式碼不會被客戶端程式載入。相當於在if (Meteor.isServer) { ... }中執行。
  4. public
    專案頂級目錄下public資料夾內的檔案可以被任何人引用。

再看Wekan的目錄結構如下,專案的程式碼結構和相互間的關係就很清晰了:

lkMacBook-Pro:wekan-setting lk$ tree -dL 2
.
├── client
│   ├── components
│   ├── config
│   └── lib
├── config
├── i18n
├── meta
│   ├── icons
│   ├── screenshots
│   └── t9n-changelog
├── models
├── node_modules
│   ├── fibers
│   ├── node-gyp
│   └── xss
├── public
│   └── fonts
└── server
    ├── lib
    ├── notifications
    └── publications

21 directories複製程式碼

通過讀文件和讀程式碼,基本上對於現有專案的結構有了個初步認識,看到各個目錄和檔案,大致知道其代表的意義,那麼接下來就是寫程式碼了。對於這種已經有了大量程式碼基礎的專案,有個優勢就是「有很多可以參考的程式碼」,可以幫助剛接觸的人更容易寫出更好的程式碼。

關於publication&subscription

開篇時談到的兩個需求,第一個是先想到的,所以剛開始是拿這個來實驗的。分析這個需求,大約有以下幾個點:

  1. 要有限制註冊的功能
    使用者註冊時,必須輸入邀請碼,否則無法註冊。

  2. 要有一個預設的管理員
    系統部署好之後,系統是可以任意註冊的,這時需要管理員去註冊一個賬號,然後這個賬號自然地成為管理員,然後他可以設定系統為僅限邀請使用者註冊。

  3. 要有邀請碼的管理
    設計一個管理頁面(Admin Panel),讓管理員可以傳送邀請,邀請通過郵件傳送,同時要可以配置Email發件地址。

這三點對於服務端的需求很簡單,首先增加兩張表,一張儲存系統的設定models/setting.js,一張儲存邀請碼models/invitationCode.js,然後在使用者的表中新增isAdmin的屬性。只要參照已有的一些表的寫法,肯定不會錯到哪裡去,另外寫的過程中再看一看官方文件中關於「Collection」的一章,很快就可以搞定了。

其中setting和isAdmin的屬性是需要publish給前端使用,結合上邊的一些知識,很容易就知道是在server/publication中稍微改動一些東西就好了。還好Meteor的文件很完整也很詳細,這部分開發沒有碰到什麼比較大的阻力。

publication和subscription之間的通訊使用了Meteor的一個自定義的RPC協議(DDP,一種基於WebSocket的自定義協議),對這個東西並沒有作更深的探究,簡單看了一下,貌似WebSocket協議是Meteor自己實現的,並沒有使用更廣為使用的WebSocket元件ws,如果伺服器不支援WebSocket,則會使用sockjs實現長輪訓 。

關於Jade&Stylus

Wekan的前端使用了一系列增加開發效率的JS元件,下面是其中涉及到賬戶系統的部分:

# Account system
accounts-password
kenton:accounts-sandstorm
service-configuration
useraccounts:core
useraccounts:unstyled
useraccounts:flow-routing複製程式碼

要修改和賬戶管理相關的東西,則首先要先去看一下這幾個元件(這裡花了很多時間,看文件看的想哭),然後Wekan的UI是用JadeStylus寫的,第一次接觸,這酸爽你懂的。幸好網上資料挺多,用習慣了之後覺得這兩個東西真的不是一般的好,強大簡介,關鍵是可以裝逼。

關於JS

隨著最近幾年node商用的越來越多,JS也已經成為成本最低的全棧開發語言,而且ES6出來之後,感覺JS其語言本身已經可以和任何一門其他語言進行媲美了,純個人觀點。

關於縮排

在開始大量寫JS之前,也寫過一段時間底層的c語言,記憶中一個Tab代表4個空格,兩個基本等價。渾然不知,Tab和空格的爭論竟然這麼激烈。

一個外行如何快速融入node專案開發
space VS tab

一直習慣寫Tab,在提交專案時,想起來run一下eslint吧,結果一大堆的錯誤。對於開源專案來說,程式碼樣式的一致性很重要,這裡還是乖乖地全部改掉了。

Meteor建議開發者遵循Airbnb style guide ,仔細去翻了翻,一些要求其實是為了提高效能,比如const的大量使用,關鍵是可讀性的提高會直接帶來程式碼可維護性的提高。

Wekan的eslint都配置好了,如果懶得配置編輯器的eslint外掛,只需要執行meteor npm run lint,如果結果如下,則可以放心提交了。

lkMacBook-Pro:wekan lk$ meteor npm run lint

> wekan@0.11.1-rc1 lint ~/github/wekan
> eslint .

lkMacBook-Pro:wekan lk$複製程式碼

後續

這裡並沒有多高深的技術討論,關於Meteor的底層實現——如DDP的實現——也並沒有作很深的探究,但是做了這個專案後拓寬了一些視野,瞭解了node作為一個新興崛起的技術的大概和發展現狀。同時出於對WebSocket的好奇也對它做了一些小小的研究,有興趣可以看一看:刨根問底HTTP和WebSocket協議

對於第二個需求,有了第一個的知識基礎,開發起來流暢了很多,很快就做出來了。

一個外行如何快速融入node專案開發
第二個feature開發完成的樣子

相關文章