:::

從PHP的Fat-Free Framework框架來看用Node.js的Express框架開發網站的心得 / Fat-Free Framework in PHP vs. Express in Node.js: Pros and Cons of Node.js

image

之前我跟學弟嘗試使用Node.js的Express框架來開發網站。本想著前端跟後端都可以統一使用JavaScript,但實際嘗試之後才發現Express框架問題頗多。這兩天為了把Zotero的資料庫寫成網站,我回頭使用PHP的Fat-Free Framework框架來開發,順手程度讓我感動到痛哭流涕,不禁想要寫一篇來整理一下Node.js的各種問題。這篇就閒聊一下吧。


Express每次修改程式碼後都需要重新啟動 / Express requires restart when code changed everytime

2017-09-18_134631

Node.js一個最出乎我意料之外的問題,就是每次修改程式碼之後都必須關閉Express、再重新啟動Express。先別提古早前開發Java時還要編譯的慘狀,我還以為自從PHP之後的網頁用程式語言都是寫了就會生效,怎想到Express的Node.js居然是要重開才能生效呢?

對沒寫程式的人來說,可能不覺得這個重新啟動的步驟有什麼特別。一般寫PHP的時候,只要改完程式、存檔、重新讀取網頁,網頁上就是修改後的內容。但是用Express來寫網頁的時候,必須是改完成、存檔、關閉Express程式、開啟Express程式(依照Node.js載入套件多寡,大概要等個5秒),重新讀取網頁、看到修改後的內容。中間多這個步驟就差了快15秒,改4次就多花1分鐘,而且那個沒有辦法作任何事情、只能等待的時間特別讓人覺得疲憊。

然而,Node.js用Express修改程式碼後需要重開的這問題不知為何很少被人提及。大家都講Node.js用JavaScript、非同步流程多棒多棒,結果這個基本又費時的缺點卻一直被人省略。

pm2-v3

網路上針對Express需要重新啟動的問題有相當多的討論,但最後的解法看來都是:換一個框架,例如PM2。換句話說,不要用Express了吧。

Express的session的各種問題 / Session issues in Express

session是儲存使用者網頁操作狀態的一種網頁技術,很常見也很普遍。在PHP中,我們可以用$_SESSION來處理session,操作方式就跟一般的變數一樣,容易使用。在Fat-Free Framework中,我們甚至可以將session資料保存在資料庫中,方便管理。這種做法在各種PHP的框架中都很常見。

然而在Express框架中,操作session就完全不是這麼一回事。Express使用session的方法會受到Express本身的版本、Express使用的各種session套件、套件本身的版本、使用套件的宣告等多種因素的影響。如果上網去找找看,你會發現Express中使用session竟然有多種寫法。像是極客學院的cookie 和 session正式作業中的Express 安全最佳作法 - Express.js這兩篇做法就不相同。我看大家爭論的關鍵點都是session的安全性,但很遺憾的是,我照這兩篇的做法來操作session,全都失敗。

Cookie也有問題 / Cookie issues in Express

session有問題,那cookie總行了吧?

跟session不一樣的是,Express的cookie寫法比較統一,沒什麼爭議。我試寫了一下,cookie也的確很容易使用。

然而,因為我的程式會用到大量的跨網域應用(我好像一直都在寫這種網頁應用程式),而cookie也會用在跨網域的狀態下儲存使用者的狀態。就在這個時候,跨網域使用GET方法傳送資料的情況下,Express的cookie就會失效。

很奇怪吧?相同網域用GET沒有問題,但是跨網域用GET就會無法儲存cookie。我還真是完全沒料到會有這種問題。

最後解決方法是用POST方法跨網域儲存cookie。沒錯,奇怪的是POST就可以正常使用。為什麼呢?

優點:容易剖析HTML / Pros: Easy HTML parsing

如果要說Node.js有什麼不可或缺的特色,我可能會說:HTML剖析。

寫前端寫習慣之後,真的會覺得用jQuery來剖析HTML程式碼真的是方便到無以復加,讓人幾乎忘了正規表示法這種複雜的玩意兒。而Node.js本身也當然是可以使用jQuery,套件是jsdom,做法可以參考「jsdom + jQuery in 5 lines with node.js」這篇。在Node.js中跑原生的jQuery,比在PHP中使用什麼PHP Simple HTML DOM Parse之類的套件來剖析HTML還要好用許多。

但如果只是為了這功能而把整個系統綁死在Node.js上,未免也太不方便了。這時候不妨可以使用PhantomJS──可以用來載入網頁內容的虛擬瀏覽器,用指令列工具來截取HTML的程式碼並剖析指定的元素內容。詳細內容可以看我之前寫的「擷取AJAX動態產生的網頁內容:PhantomJS指令列工具」。


小結 / In closing

如果你在看這篇的時候,一直在質疑為什麼我沒有提到PHP的幾個問題:

  • 不夠物件導向、太過程序化的寫法 (但Express其實也蠻程序化)。
  • 檔案即網址造成的安全性問題,沒有Express的路由工具(routing)好用。
  • 未支援新形態的資料庫,例如Redis。(不知道為什麼,很多人寫Express會搭配Redis使用)

如果你有這些問題,那可能是因為你不太知道現在PHP的發展早已經克服這些問題了。現在撰寫PHP的時候很少人是從白紙來寫網頁,而是會從框架(framework)開始撰寫。PHP知名的框架LaravalCodeIgniter實在是過於複雜,我現在最推薦的是Fat-Free-Framework (f3),它涵蓋了幾乎我需要的各種功能,並簡潔到讓人足以快速上手。

  • f3的路由跟Express的做法類似,還可以透過config.ini設定路由
  • f3的路由會鼓勵開發者用物件導向開發
  • PHP後來就支援Redis了,請照「PHP 使用 Redis」設定。
  • f3的模板功能(template)非常好用。

不過,就算PHP多方便,我還是會希望能在後端使用JavaScript。能使用相同語言開發程式,其實真的感覺很好,就是上面寫的那些缺點討厭了些XD

總共4 則留言 ( 我要發問 , 隱藏留言 顯示留言 )

  1. PHP 在 Html Parser 有一個套件還蠻好用的,給你參考看看
    http://symfony.com/doc/current/components/dom_crawler.html

    也是用 css selector 的方式去抓 DOM

    回覆刪除
  2. Take a look at the article about Node.js pros and cons - https://www.cleveroad.com/blog/node-js-vs-ruby-on-rails--the-power-behind-technologies
    Good luck!

    回覆刪除
    回覆
    1. Thanks!
      But I still prefer JavaScript (Node.js) to Ruby, however.

      刪除