Middleman v4のExternal Pipelineてpreprocess全般に使えるのでは?
ちょっと試しに 4.2.1 でやってみたんだけど、
activate :external_pipeline, {
name: :dumb_command,
command: 'echo "dumb command ..."',
source: ''
}
みたいな設定が可能ということが分かった。
つまり、
- External Pipeline は名前をつけて外部コマンドを呼ぶだけなので、build 前になんでもさせられる
- ただし、source 指定は必須なので空文字を入れておけば ok
- nil はダメ
ということか。
外部の API からデータを取得するとかもこれでイケるんだな。Data Files を保存する何かを作ってしまえばなんでもできる。Headless CMS との連携とか。無理に内部構造を理解して Extension を作る必要もない。1
これ、いいんじゃないか?
順番はどうなる?
複数の External Pipeline を指定した場合、
- 実行する順番は activate した順番
- ただし build 時以外は default ではスレッドで動くので external pipeline の 実行結果を得る順番は保証できない
- disable_background_execution: true 指定を加えると制御可能
ということは
- 順番に依存する処理を watch 時に行わないのが基本
- どうしてもという場合は disable_background_execution: true 指定を追加
- その場合は hot reload / live reload 系はたぶん無理
- 順番に依存する処理はそれを起動する sh script などの方で制御する
といった工夫が必要になる。
ちなみにコードで言うとこの辺
class Middleman::Extensions::ExternalPipeline < ::Middleman::Extension
self.supports_multiple_instances = true
option :name, nil, 'The name of the pipeline', required: true
option :command, nil, 'The command to initialize', required: true
option :source, nil, 'Path to merge into sitemap', required: true
option :latency, 0.25, 'Latency between refreshes of source'
option :disable_background_execution, false, "Don't run the command in a separate background thread"
..
if app.build? || options[:disable_background_execution]
watch_command!(false)
..
def watch_command!(async)
@current_thread = ::Servolux::Child.new(
command: options[:command],
suspend: 2
)
@current_thread.start
watch_thread = Thread.new do
もちろん CMS 提供側としては gem で配布できることはアピールポイントになるのでちゃんと Extension 作った方がいいけど。 ↩