位元詩人 用 plenv 及 Carton 建立自給自足的 Mojolicious 網頁程式

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

本文展示一個「現代 Perl 網頁程式設計」的起手式,提供給想使用 Perl 開發後端(Backend)的讀者參考。

系統需求

  • 主流 GNU/Linux 發行版(本文指令在 openSUSE Leap 16 上操作驗證)
  • Perl
  • Git
  • C 編譯器(通常為 GCC)

安裝 plenv

plenv 的目的在於個人環境中安裝特定版本的 Perl,讓開發者不再受限於系統內建的 Perl 版本與套件。

請輸入以下指令安裝 plenv

$ git clone https://github.com/tokuhirom/plenv.git ~/.plenv

本文以 Bash 為例,請在 ~/.profile 檔案中加入以下內容:

PATH="$PATH:${HOME}/.plenv/bin"
export PATH

eval "$(plenv init -)"

重新登入 Shell 讓指令生效。也可以用以下指令直接引入改好的設定檔:

. ~/.profile

安裝 Perl-Build

Perl-Build 是用於安裝個人環境 Perl 的外掛,可與 plenv 完美搭配。請輸入以下指令進行安裝:

$ git clone https://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/

安裝本地端的 Perl

在本文撰寫時,Perl 的最新穩定版本為 5.42.2。請輸入以下指令安裝該版本的 Perl:

$ plenv install 5.42.2

編譯需要一些時間,請稍作等待。

安裝完成後,設定在個人全域環境中使用該版本的 Perl:

$ plenv global 5.42.2

若未來在特定專案中沒有指定 Perl 版本,系統便會自動採用這個全域版本。

安裝 cpanm

建議順便安裝 cpanminus(cpanm):

$ plenv install-cpanm

安裝後即可使用 cpanm 來下載 Perl 模組。它比傳統的 cpan 指令更加簡潔高效,且不會詢問使用者一堆繁瑣的設定問題。

安裝 Carton

Carton 是現代 Perl 開發中不可或缺的相依性管理工具,功能相當於 Ruby 的 Bundler。請輸入以下指令進行安裝:

$ cpanm Carton

建議之後所有的 Perl 模組都透過 Carton 安裝在各別專案內,儘量避免全域安裝,以防發生套件相依性衝突。

建立專案

請輸入以下指令建立空白專案,並進入該專案的根目錄:

$ mkdir myapp
$ cd myapp

接著指定該專案所使用的 Perl 版本:

$ plenv local 5.42.2

執行後,該專案的 Perl 版本便會鎖定在 5.42.2。不過由於 Perl 具備極佳的向後相容性,此步驟並非強制必要。

手動建立一個名為 cpanfile 的文字檔案(注意沒有副檔名),並加入以下內容:

requires 'Mojolicious', '9.45';

on 'develop' => sub {
    requires 'Test::Mojo';
};

接著使用 Carton 為專案安裝所有相依套件:

$ carton install

此時系統會自動產生 cpanfile.snapshot 設定檔,用來精確鎖定 Perl 模組的相依版本。

未來若要將專案加入版本控制(如 Git),請務必將 cpanfilecpanfile.snapshot 兩者都納入版控,如此才能在其他環境完整還原專案狀態。

若是在正式生產(Production)環境,請改用以下指令進行安裝:

$ carton install --deployment --without develop

這樣就能跳過不必要的開發時期模組,讓環境更乾淨。

建立主程式

手動建立一個名為 myapp 的指令稿(可省略副檔名),並加入以下程式碼:

use v5.36;

use FindBin;
use local::lib "$FindBin::Bin/local";

use Mojolicious::Lite -signatures;

get '/' => sub($c) {
    $c->render(text => "Hello World\n");
};

app->config(hypnotoad => {
    listen => ['http://127.0.0.1:8080'],
    proxy => 1,  # Behind Nginx
});

app->mode('production');

app->start;

這段程式碼相當於 Mojolicious 的 Hello World 範例。為了精簡篇幅,在此不逐行說明程式碼細節。

接著,在背景啟動 Mojolicious 網頁伺服器:

$ carton exec hypnotoad myapp

啟動後,可以使用 curl 指令驗證網頁程式是否正常運作:

$ curl http://127.0.0.1:8080
Hello World

將主程式移至 bin/ 目錄

如果你偏好將主程式收納到 bin/ 資料夾下,只需將引入 local::lib 的路徑修改為上層目錄即可:

use local::lib "$FindBin::Bin/../local";

處理路徑與相依性

在此架構中,專案內部的自訂套件會放在 lib/,而透過 Carton 安裝的第三方套件則會自動存放在 local/。在引入路徑時,建議優先載入第三方套件,接著再載入內部套件:

use local::lib "$FindBin::Bin/local";
use lib "$FindBin::Bin/lib";

上版本控制

在設定版本控制時,可參考標準的 Perl.gitignore,並額外加入以下專案專屬的忽略項目:

*.pid
*.log

至此,我們已成功建立一個符合現代化標準的 Perl 專案架構,日後不論是部署或銜接 CI/CD 流程都非常方便。

關於作者

位元詩人 (ByteBard) 是資訊領域碩士,喜歡用開源技術來解決各式各樣的問題。這類技術跨平台、重用性高、技術生命長。

除了開源技術以外,位元詩人喜歡日本料理和黑咖啡,會一些日文,有時會自助旅行。