這兩天我整理出安裝 Yesod 網站框架的經驗。
先介紹環境因素:作業系統二份,一是在高階電腦的 Ubuntu ,二在舊電腦 (Toshiba Pretege Z830) 的 ArchLinux 。軟體架構就是由 GHCup 扛起全部 Cabal 、 GHC 、 Stack 等軟體,並且以 Stack 為主。
Stack 全域設定以最新版 resolver: LTS-22.1
。(昨天查網站 https://stackage.org/ 還看到 LTS-22.0 最新,而今天早上看到是 LTS-22.1 了。)
正式安裝步驟
首先按照 Yesod 官方網站的 “Get Started" 操作安裝指令。不過,可照著我如下的見解。
如上我說的,全域配置的 Stack resolver 為最新套件,但是,這個最新套件,用得上嗎?
敲指令:
stack new my-project yesodweb/sqlite
然後,瀏覽指令之下的回應訊息:從第一行回應訊息可見:
正在下載 yesodweb/sqlite 模板;
yesodweb/sqlite 模版下載完畢。
正在判讀用 Cabal 或 package.yaml 來處理本專案 my-project ...
決定使用 my-project 的專案設定檔。
而查看檔案 my-project/stack.yaml
裡,寫了 resolver: https://raw.github ... /LTS/20/26 ...
,表示即便全域 Stack 設定為 LTS-22.1
但專案 my-project 仍要用設定 LTS-20.26
。這是因為專案模板 https://github.com/yesodweb/stack-templates/sqlite.hsfile 已指明了一套 package.yaml
程式版本清單,而指令 stack new ...
核對該份清單,與 https://stackage.org/
站內提供的諸 LTS-*
套件互相比對,真的只找得到 LTS-20.26
適合。
於是,如果我在非 my-project 路徑操作任一 stack
指令,將用到 LTS-22.1
。
而只要我在專案路徑 my-project/
裡敲 stack
指令,例如 stack build
,則將用到 LTS-20.26
。
現在,也不必敲指令 ghcup tui
之類的,去調控 Cabal 、 GHC 、 Stack 三份一組軟體的版本。全域有哪幾個版本,就有哪幾個版本,反正都不必管全域有哪些。
只要在專案路徑 my-project/
裡頭,繼續敲指令即可。
並由於 LTS-20.26
搭配較舊版本 Cabal 、 GHC 、 Stack ,我可以先用 GHCup 安裝那幾個版本。由網頁 https://stackage.org/lts-20.26 可查閱三件軟體各件的版本號碼。
所以,接著敲以下指令,為編譯並建置網站專案 my-project
:
stack build
當網站編譯好了之後,要將網站執行起。執行方式,須由執行工具 yesod-bin
啟動。
套件名稱 yesod-bin
提供主執行檔 yesod
,可搭配許多指令,例如指令 yesod devel
可啟動指定的網站專案。
安裝 yesod-bin
同樣在路徑 my-project/
敲安裝指令,可順暢處理版本依賴關係:
stack install yesod-bin
但主執行檔 yesod
將放到用戶基礎目錄 ~/.local/bin/
,而不會留在專案目錄 my-project/
裡。
啟動網站
在路徑 my-project/
裡敲以下指令:
stack exec -- yesod devel
Stack 操作指令有個「轉接」的指令風格,用兩個連字符號 “--
” 將 Stack 執行權與相關參數轉嫁給其他指令。所以,啟動網站專案 my-project
的指令長得如以上樣子。
我在 Ubuntu 練習安裝 Yesod ,如上述一般順暢。
但是,在 ArchLinux 遇到些困難。專案模板指定的軟體 language-javascript-0.7.1.0
,編譯時遇到字碼讀取問題。
在檔案 src/Language/JavaScript/Parser/Grammar7.y
第 1453 行,有個數學符號「左項不包含於」。軟體 happy
回報錯誤訊息為 “invalid byte sequence" 。
然後,我瀏覽了 language-javascript 的 GitHub Issue 對話紀錄,以及在 Stackoverflow.org 的問答紀錄,得知在此有個理念之爭:軟體 happy
讀取 language-javascript
程式碼的方式,應該足以讀進 UTF-8 字碼,但是, Cabal 、 Stack 軟體開發觀念,則認為該就著從網路上讀到哪種字碼,就處理哪種字碼,而不該將讀取手段綁死在用戶系統限定的字碼 locale
。由於雙方沒妥協意願,如軟體 langaguea-javascript
字碼問題,成為兩不管地帶。
解決方式,靠用戶自己想辦法搞定。
在 ArchLinux 安裝 Yesod
我的經驗,我給指令提供了中立的 UTF-8 解碼要求,就順暢地處理 Yesod 編譯與建置了:如以下指令,
LANG=C.UTF-8 stack build
而之前我試過好幾遍的另一些指令,如下,都沒用;一直看到軟體 happy
無法如實讀取檔案 Grammar7.y
。
LANG=en_US.UTF-8 stack build
LANG=zh_TW.UTF-8 stack build