scaffdogとHygenの比較
ざっくりとした印象
- scaffdogは簡潔、単純なテンプレート生成向き
- hygenはいろいろできる、玄人向け
Storybookの雛形生成してほしいくらいならscaffdogのほうが良さそう
複雑なテンプレート書きたいならejsでまとめてかけるhygenは便利そう
Reactコンポーネントの雛形生成にどちらを採用しようかなということで比較
scaffdogは日本人の方が作っているということもあって前に使ったことあるけど、知らないアプデがある
厳密には v2.0.0 ではなく、v2.4.0 以降の変更が含まれていますが、以下 v2 の主な変更点です。
- ドキュメントサイト
- 設定ファイルの形式追加
- 構文の拡張
- 対話型プロンプトの完全スキップ
- プロンプト種類の追加
- プロンプトに対する条件追加
- ファイル生成の条件分岐
- ヘルパー関数の追加
- その他細かい点
まずはscaffdogから
minimal setupはnpx scaffdog init
で完了
すんごい丁度いい例
// Button/index.ts
export * from './Button';
// Button/Button.ts
export type Props = React.PropsWithChildren<{}>;
export const Button: React.FC<Props> = ({ children }) => {
return <div>{children}</div>;
};
// Button/Button.stories.ts
import { Button } from './Button';
export default { component: Button };
export const Overview = { args: {} };
テンプレートファイル内で変数が定義できる
# Variables
- constant_key: scaffdog
- computed_key: `{{ inputs.name | upper }}`
# `filename.txt`
``
{{ constant_key }}
{{ computed_key }}
``
条件分岐もできる。下記の例だとinput.testがtrueなら生成
---
name: 'component'
root: '.'
output: '.'
questions:
test:
confirm: 'Do you need a test?'
initial: true
---
# `{{ inputs.test || "!" }}index.test.ts`
``typescript
// ...
``
プロンプトの形式について
いけるやつ
- テキスト入力
- y/n
- 選択肢(単数/複数選択)
補助機能
- 初期値OK
- 条件分岐OK
条件分岐の式はbuiltin helperで書いてるっぽい
questions:
name:
message: 'Please enter a component name.'
# Invokes confirm prompt only when input includes "Form".
test:
if: contains(inputs.name, 'Form')
confirm: 'Do you need a test?'
基本的にJSっぽく書ける
式も書けるようになってる、すごいな
{{ inputs.value }}
{{ null }}
{{ undefined }}
{{ true }}
{{ false }}
{{ 10 }}
{{ 2 + 3 }}
{{ "string" }}
コメントも書ける
{{ /* a comment */ }}
いい感じのHelper多数。パイプも行ける。
{{ relative "../" }}
{{ len(inputs.value) }}
{{ replace(inputs.value, "-", "") }}
{{ inputs.value | upper }}
{{ inputs.value | replace ".ts$" ".js" | pascal }}
{{ output.base | replace output.ext ".js" | pascal }}
三項演算子
{{ <expression> ? <expression> : <expression> }}
if文。選択形式の入力に合わせてって感じかな。ちょっと読みづらい。
{{ if len(inputs.value) > 5 }}Long{{ end }}
{{ if len(inputs.value) > 5 }}Long{{ else }}Not long{{ end }}
{{ if len(inputs.value) > 5 }}Long{{ else if len(inputs.value) > 2 }}Medium{{ end }}
{{ if len(inputs.value) > 5 }}Long{{ else if len(inputs.value) > 2 }}Medium{{ else }}Short{{ end }}
配列に合わせて?for loop
{{ for v in seq 1 5 }}{{ v }}{{ end }}
{{ for v, i in seq 1 5 }}{{ v + i }}{{ end }}
{{- /* continue and break */ }}
{{ for v in seq 1 5 }}{{ if v == 2 }}{{ continue }}{{ end }}{{ v }}{{ end }}
{{ for v in seq 1 5 }}{{ if v == 2 }}{{ break }}{{ end }}{{ v }}{{ end }}
Whitespaceのtriming
// input
before {{- "text" }} after
before {{ "text" -}} after
before {{- "text" -}} after
// output
beforetext after
before textafter
beforetextafter
設定に便利なbuilt in変数も多数用意
helper関数まじで増えたな、表現に困ることはなさそう
{{ read output.abs }}
で出力ファイルの内容を読み込めることになるので、Injectionができる。条件分岐と組み合わせて可読性UP的な感じかな?よくわからない
# `index.js`
``javascript
console.log('first line');
{{ read output.abs }}
``
``javascript
{{ read output.abs | before 6 }}
console.log('line at 6');
{{ read output.abs | after 6 -1 }}
``
グローバル変数、カスタムヘルパー、カスタムタグの設定が可能。
なんでもできるな。
generateのときに対話スキップも可能
$ scaffdog generate component \
--force \
--output "buttons" \
--answer "name:OutlinedButton" \
--answer "test:true" \
--answer "type:A" \
--answer "type:C"
# output --> src/components/buttons/OutlinedButton
テンプレートファイルをPretteirでフォーマットするプラグイン。経験者としては結構嬉しいやつな気がする。
ドキュメントなんか可愛くてよかった。たぶんChakra UI
次はHygen
hygen init self
でsetup
- bodyはejs
- helper関数多数
- かなりリッチなInjection
- shell actionが使える
例ではpackageの追加と自動インストールが挙げられている。使うか?
---
inject: true
to: package.json
after: dependencies
skip_if: lodash
sh: cd <%= cwd %> && yarn install
---
"lodash":"*",
shellが使えるので使いこなせばできることはscaffdogよりはるかに多そう。
単なるテンプレートとして使うならejsは好み分かれそう、自分はscaffdogの記法のほうが好き
scaffdogは複数ファイルの出力を1つのファイルで定義するが、hygenは1つのファイルを出力するのに1つのテンプレートファイルを用意して、1つのコマンドに対して1つのフォルダでまとめているみたい。
$ hygen GENERATOR ACTION:SUBACTION
という構文で使うため、テンプレートをかなり構造化して管理できる。
promptはこんな感じで定義。わかりやすいっちゃわかりやすい。
module.exports = [
{
type: 'input',
name: 'message',
message: "What's your message?"
}
]
promptの設定もJSでかなり色々できるみたい
// my-generator/my-action/index.js
module.exports = {
prompt: ({ prompter, args }) =>
prompter
.prompt({
type: 'input',
name: 'email',
message: "What's your email?"
})
.then(({ email }) =>
prompter.prompt({
type: 'input',
name: 'emailConfirmation',
message: `Please type your email [${email}] again:`
})
)
}
これが代表的なツールで、Hygenはそのオルタナティブとして作られたっぽい。FAQより。
Usecaseが提示されているのはいいね
Injectionをうまく利用してexpressのroute追加とかをCLIからできるようにするのが載ってた。なるほどだけどSnippetでよくね。
ふつうに自分が読めてないだけだと思うんだけど、ドキュメントがかなり読みづらい気がする。
触りながら理解してくれってことだろう。