npm init や yarn create でジェネレータを利用できる理由
Next.js や Slidev などのフロントエンドのOSSで npm init slidev
や npx create-next-app
のようなテンプレートからプロジェクト作成するためのジェネレータが用意されており、なぜ npm init
や npx
など複数の方法でジェネレータを利用できるのか気になったので調べました。
パッケージ名にルールがある
NPMのドキュメントに npm init
がジェネレータを認識するためのルールが記載されており、
どうやら create-<name>
のような特定のルールでパッケージ名を指定するとジェネレータとしてNPMが認識してくれるようです。
具体的なルールは下記になります。
npm init <@scope> (same as `npm exec <@scope>/create`) npm init [<@scope>/]<name> (same as `npm exec [<@scope>/]create-<name>`)
パッケージを scoped-module として作成する場合は、@thasmto/create
のようにスコープ名の後ろに create
をつけたパッケージ名にすることで npm init @thasmto
で実行できるようになります。
また、 scoped-module ではない場合でも create-thasmto
のように create-
から始まるパッケージ名にすることで npm init thasmto
と実行できます。
本来、npm init
は新しい package.json
を作成するために利用されますが、上記のルールに当てはまるパッケージが存在する場合は、内部で npx exec
というコマンドが動きます。
そして npm exec
はパッケージのコマンドを実行するためのコマンドであり、エイリアスとして npx
が用意されています。
このことから以下の三つコマンドは同じパッケージを実行することがわかりました。
npm init next-app npm exec create-next-app npx create-next-app
また、yarn create
も npm init
と同様に create-*
と名前付けされたパッケージを実行できます。
おわり
普段あまり意識することはないですがちょっとした疑問を解消をできました。 実際にジェネレータを作るには、テンプレートからプロジェクトディレクトリを生成するためのNode.jsのスクリプトを書く必要がありますが、その場合は下記の記事が参考になりそうでした。