Closed25

scaffdogとHygenの比較

ピン留めされたアイテム
hajimismhajimism

ざっくりとした印象

  • scaffdogは簡潔、単純なテンプレート生成向き
  • hygenはいろいろできる、玄人向け

Storybookの雛形生成してほしいくらいならscaffdogのほうが良さそう

hajimismhajimism

複雑なテンプレート書きたいならejsでまとめてかけるhygenは便利そう

hajimismhajimism

Reactコンポーネントの雛形生成にどちらを採用しようかなということで比較
https://scaff.dog/
https://www.hygen.io/

hajimismhajimism

scaffdogは日本人の方が作っているということもあって前に使ったことあるけど、知らないアプデがある

https://blog.wadackel.me/2022/scaffdog-v2/

厳密には v2.0.0 ではなく、v2.4.0 以降の変更が含まれていますが、以下 v2 の主な変更点です。

  • ドキュメントサイト
  • 設定ファイルの形式追加
  • 構文の拡張
  • 対話型プロンプトの完全スキップ
  • プロンプト種類の追加
  • プロンプトに対する条件追加
  • ファイル生成の条件分岐
  • ヘルパー関数の追加
  • その他細かい点
hajimismhajimism

まずはscaffdogから
https://scaff.dog/docs

hajimismhajimism

すんごい丁度いい例

// 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: {} };
hajimismhajimism

https://scaff.dog/docs/templates

テンプレートファイル内で変数が定義できる

# 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
// ...
``
hajimismhajimism

プロンプトの形式について
https://scaff.dog/docs/templates/attributes

いけるやつ

  • テキスト入力
  • 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?'
hajimismhajimism

https://scaff.dog/docs/templates/template-engine

基本的に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
hajimismhajimism

https://scaff.dog/docs/templates/injection
{{ 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 }}
``
hajimismhajimism

generateのときに対話スキップも可能

$ scaffdog generate component \
    --force \
    --output "buttons" \
    --answer "name:OutlinedButton" \
    --answer "test:true" \
    --answer "type:A" \
    --answer "type:C"

# output --> src/components/buttons/OutlinedButton
hajimismhajimism

ドキュメントなんか可愛くてよかった。たぶんChakra UI

hajimismhajimism
hajimismhajimism

https://www.hygen.io/docs/templates

  • 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の記法のほうが好き

hajimismhajimism

scaffdogは複数ファイルの出力を1つのファイルで定義するが、hygenは1つのファイルを出力するのに1つのテンプレートファイルを用意して、1つのコマンドに対して1つのフォルダでまとめているみたい。

hajimismhajimism

https://www.hygen.io/docs/generators

$ 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:`
        })
      )
}
hajimismhajimism

Usecaseが提示されているのはいいね
https://www.hygen.io/docs/express

Injectionをうまく利用してexpressのroute追加とかをCLIからできるようにするのが載ってた。なるほどだけどSnippetでよくね。

hajimismhajimism

ふつうに自分が読めてないだけだと思うんだけど、ドキュメントがかなり読みづらい気がする。
触りながら理解してくれってことだろう。

このスクラップは2023/01/14にクローズされました