olNGIb4NkK5r2x7x4oG3GpEzizVpnY6KNCck9cym

我是如何將部署 TiddlyWiki 的命令,轉換為入口腳本文件的?

這篇記錄我是怎麼將部署 tiddlywiki 服務的命令,轉換為入口腳本文件的。

筆者於 如何在使用 cPanel 面板的虛擬主機上部署 TiddlyWiki 服務? 一文中提到,在 TiddlyWiki 官方文件 中所提供的部署方式,是使用 tiddlywiki 命令啟用服務,因此許多文章中部署方法是使用 pm2 來管理 Node.js 行程:

TiddlyWiki 官方網站提供的部署方式,是使用 'tiddlywiki' 命令啟用服務
TiddlyWiki 官方網站提供的部署方式,是使用 tiddlywiki 命令啟用服務

然而在虛擬主機(shared hosting)上要部署 Node.js 文件卻需要提供入口腳本文件,那麼筆者是 如何將部署 TiddlyWiki 的命令,轉換為入口腳本的 呢?整體的想法其實並不複雜,首先我們必須要理解以下概念:

  • 我們所執行的任何命令或程式,通常會以兩種形式進行,一種是「程式專案經編譯後的二進制執行檔」或者是「交由直譯器運行的腳本文件」;當然,直譯器本身其實也是一種編譯後的二進制執行檔。
  • 大多數使用 Node.js 安裝的命令是屬於「交由直譯器運行的腳本文件」,這意味著我們可以找到腳本的原始文件。

那麼問題就變成是要找到對應的腳本文件了!我們可以使用 npx which [COMMAND] 來查詢使用 npx 執行的命令所在的路徑:

$ npx which tiddlywiki
/home/hhpeng/domains/memo-demo.hhpeng.org/application/node_modules/.bin/tiddlywiki

使用 npx 執行命令時,通常會下載或建立一個臨時執行檔於 /node_modules/.bin/ 目錄中,因此該文件並非實際的文件,可以再透過 ls 命令檢查軟連結(soft link)指向的路徑:

$ ls -l --all $(npx which tiddlywiki)
lrwxrwxrwx 1 hhpeng hhpeng 27 Apr 14 03:00 /home/hhpeng/domains/memo-demo.hhpeng.org/application/node_modules/.bin/tiddlywiki -> ../tiddlywiki/tiddlywiki.js

據此我們可以得知在運行 tiddlywiki 命令時,實際上是使用 node 執行 tiddlywiki.js 腳本:

#!/usr/bin/env node

/*
This is invoked as a shell script by NPM when the `tiddlywiki` command is typed
*/

var $tw = require("./boot/boot.js").TiddlyWiki();

// Pass the command line arguments to the boot kernel
$tw.boot.argv = Array.prototype.slice.call(process.argv,2);

// Boot the TW5 app
$tw.boot.boot();

如此一來,我們只需要根據其內容改寫便可以得到如下的 app.js 入口文件了:

const tw = require('tiddlywiki').TiddlyWiki();

tw.boot.argv = ["memo", "--listen", "credentials=../users.csv", "readers=(anon)", "writers=(authenticated)", "admin=H.-H."];
tw.boot.boot();

我所異動的地方有二:

  1. 執行時,虛擬主機會啟用對應的虛擬環境,該環境中已經使用 npm install 安裝了 tiddlywiki 套件,因此可以直接使用 require('tiddlywiki') 引入物件。
  2. 原始腳本中由於是供執行命令使用,因此命令參數需要透過 process.argv 餵入;在我們已知要使用哪些參數的情況下,可以將陣列中的元素寫死。

張貼留言