node.js with Express, Jade, Stylus and CoffeeScript

好像不用 node.js 寫一些小東西感覺不出來他的威力 而且小郭說每次 Demo 都用 Hello World!

所以決定動手寫一個小小的留言板

搭配的 Framework 有 Express CoffeeScript Jade Stylus

這些 Framework 功能如下

  • Express : 是 node.js 的 Web Framework
  • CoffeeScript : 是快速產生 Javascript 的好物!
  • Jade : HTML 的 Template Engine
  • Stylus : dynamic stylesheet 簡單的語言產生 css

功能有

  • 新增留言
  • 修改留言
  • 刪除留言

Demo site 在 Cloud Foundry


是透過 VMware 的 Cloud Foundry 執行的

Source Code 在 GitHub


以下是說明
首先請先確認你的環境已經裝好 node.js, npm, 與 Express

接下來在想要的目錄輸入


會產生如下的目錄架構

大概就是這樣


其中的 app.js 就是主程式裡面包含了 routing 也是 controller

順帶一提的是 Express 沒有什麼 MVC 的架構(或者說可以自己切 XD) 感覺上他只有包含了 Controller 跟 View

因為我們的計畫跑在 VMware Cloud Foundry 上, 所以要加上 package.json 內容如下


再下指令


npm 1.0 之後用 npm install -d

npm 就會幫我們把需要的 Framework 通通裝到 node_modules 裡了

所以目前目錄結構如下


都準備好之後終於可以開始寫程式了 XD

因為 express 在產生目錄時我們有指定 jade 跟 stylus 當 html 跟 css 的 engine 但是 CoffeeScript 還沒有指定

所以為了讓 Express 能吃到 CoffeeScript 所以我們先在 app.js 的 app.configure 裡加上一行 app.use(express.compiler({src: __dirname + ‘/public’, enable: [‘coffeescript’]}));

也就是會長這樣拉
這是 app.js 的片段而已


所以這樣一來我們的環境也就是 express 就可以支援
  • .jade 都放在 ./views 底下 由 Jade 翻譯
  • .styl 都放在 ./public/stylesheets 底下 由 Stylus 翻譯
  • .coffee 都放在 ./public/javascripts 底下 由 CoffeeScript 翻譯

另外為了讓我們的環境可以吃 npm bundle 包的內容以及準備一些環境變數我們把 app.js 開頭改成


express 的 Controller-View 的 架構非常簡單

以下圖來說 (取自 app.js 的一段)


  1. app.get(參數1, 參數2) 的 參數1 是接收的網址 比方說 當網址是 http://xxxxx/ 而且方法是 Get 時就會交由這個 Controller 的 參數2 去處理 ( 參數2 必須是 function!)
  2. res.render(參數1, 參數2) 的 參數1 是告訴 Jade 要用哪一個 template 去 render 結果上圖表示要用 index.jade 去 render 結果
  3. res.render(參數1, 參數2) 的 參數2 就是傳遞給 index.jade 的變數 type 必須是 JSON

Controller 跟 View 的合作很簡單吧 接下來我們看一下 View 怎麼做的

首先看 ./views/layout.jade


第一行的 !!! 5 表示要用 html5 的 doctype 輸出!

再來是 ./views/index.jade


如果剛剛 res.render 參數2 的 JSON 裡沒有 layout:false 則所有的結果都會是 layout.jade + 參數1.jade 輸出

所以以剛剛的範例來說 title: ‘Hello Cloud Foundry’ 就會被 layout.jade 的 title= title 吃走

而 articles: articles 就會被 index.jade 裡面 - each article, key in articles 的 articles 吃走

詳細的 Jade 使用方法可以參考 Jade 官網

因為要寫出類似留言板的網站所以我們要一個存檔的功能

接下來我們來新增一個 save 的 Controller 方法是 POST 收的參數有一個就是 textarea 裡的 value 啦

所以請在 app.js 裡新增 一個 app.post(‘/save’, function(){}) 的 method 如下


POST 或 GET 收進來的變數都會由 req.body.[變數] 來取得

這邊的設計上 db 裡每一筆資料都是 JSON 裡面有兩個資料 一個是文章 id (由 md5 hash) 是做刪除用的 另一個是文章內容 content

而 render 的結果是由 save.jade 處理所以 res.render 的 參數1 我們填 ‘save’

參數2 必須是個 JSON 我們傳了三個東西
  1. id : 文章 id
  2. content : 文章內容
  3. layout : 要不要套用 layout.jade, 這裡是 false 表示單純輸出 save.jade 的內容就好

BTW, 這邊的 db 其實我是用 array 做的 可以參考app.js 因為 VMware Cloud Foundry 目前還沒支援任何 database (之後會有 MySQL, Redis, 和 MongoDB 的支援)

再來我們看一下 save.jade


原理很簡單 就是把整塊 div 回傳回去到網頁端的 javascript 直接整個 append 上去就好 (簡單來說我把它當 template 用 XD)

再來進階一點我們還想要有修改的功能 一樣的 Controller 只是變成判斷有沒有 文章id 如果有的話就進去 db 尋找 id 有沒有 match 有的話就修改他 沒有文章 id 表示新增文章 因此 Controller 變成這樣


最後我們來稍微看一下 Stylus 跟 CoffeeScript 吧

首先是 ./public/stylesheets/style.styl


Stylus 翻譯出來就變這樣!

P.S. 我有偷偷修改 app.js 的 app.configure 裡面的 Stylus 加上了 compress : true 讓 translate 出來的 css 有壓縮!

至於 javascript 的處理 我們看 ./public/javascripts/hello.coffee


ㄜ… 這邊要解釋起來有點囉嗦改天再寫一篇 blog 目前請各位去看 docs 吧 XD

CoffeeScript 翻譯過的結果就是這樣


很酷 對吧!

Comments

Tim Wu
呵! 正在看這方面的資料, 想不到台灣有人try 這麼快.