ジェネレータ generator-generator を紹介します。このエントリーは「YEOMAN Advent Calendar 2014」12月22日の記事です。
YEOMAN Advent Calendar 2014 - Adventar
generator-generator とは
generator-generator とは generator を作るためのジェネレータです。既存のジェネレータを参考に拡張していく方法もありますが、一から自分で作る場合このジェネレータを使うと良い(かもしれない)です。いつもと同じようにインストールしていきます。
$ npm install -g generator-generator
今回は何かしらのジェネレータを作りますので generator-work というディレクトリを作りそこでジェネレータを作ります。
$ mkdir generator-work && cd $_ $ yo generator
yoコマンドでジェネレータに関することを聞かれます
- githubアカウント
- ジェネレータ名(今回はhelloworld)
そうして作られたファイルが
yo コマンドで作ったジェネレータを実行するための準備
作成したジェネレータを実行するためにnpmが認識できるパスにファイルを置く必要があります。ただしファイルを移動したりするとめんどうなのでリンクで代用します。自分の場合はnodebrewを使ってます。
$ pwd /Users/albatrosary/.nodebrew/current/lib/node_modules $ ln -s /Users/albatrosary/Project/generator/generator-helloworld generator-helloworld
リンクができたら実行します。
$ mkdir helloworld && cd $_ $ yo helloworld _-----_ | | .--------------------------. |--(o)--| | Welcome to the | `---------´ | perfectHelloworld | ( _´U`_ ) | generator! | /___A___\ '--------------------------' | ~ | __'.___.'__ ´ ` |° ´ Y ` ? Would you like to enable this option? Yes create package.json create bower.json create .editorconfig create .jshintrc I'm all done. Running bower install & npm install for you to install the required dependencies. If this fails, try running the command yourself. npm WARN package.json package@0.0.0 No description npm WARN package.json package@0.0.0 No repository field. npm WARN package.json package@0.0.0 No README data $
詳細
generator-generatorに関する詳細は YEOMANサイト に記載があります。
Writing Your Own Yeoman Generator | Yeoman
今回はここから一部を。app/index.js が基本的にyoコマンドで実行されるファイルです。ここに幾つかメソッドを追加して実行してみます。追加するメソッドは
method1: function () { console.log('method 1 just ran'); }, method2: function () { console.log('method 2 just ran'); },
です。これはyeoman.ioにも記載されているサンプルです。全体としては次のようになります。
'use strict'; var yeoman = require('yeoman-generator'); var chalk = require('chalk'); var yosay = require('yosay'); module.exports = yeoman.generators.Base.extend({ initializing: function () { this.pkg = require('../package.json'); }, method1: function () { console.log('method 1 just ran'); }, method2: function () { console.log('method 2 just ran'); }, prompting: function () { var done = this.async(); // Have Yeoman greet the user. this.log(yosay( 'Welcome to the perfect' + chalk.red('Helloworld') + ' generator!' )); var prompts = [{ type: 'confirm', name: 'someOption', message: 'Would you like to enable this option?', default: true }]; this.prompt(prompts, function (props) { this.someOption = props.someOption; done(); }.bind(this)); }, writing: { app: function () { this.fs.copy( this.templatePath('_package.json'), this.destinationPath('package.json') ); this.fs.copy( this.templatePath('_bower.json'), this.destinationPath('bower.json') ); }, projectfiles: function () { this.fs.copy( this.templatePath('editorconfig'), this.destinationPath('.editorconfig') ); this.fs.copy( this.templatePath('jshintrc'), this.destinationPath('.jshintrc') ); } }, install: function () { this.installDependencies({ skipInstall: this.options['skip-install'] }); } });
これを実行するとコンソールは次のように表示されます。
$ yo helloworld _-----_ | | .--------------------------. |--(o)--| | Welcome to the | `---------´ | perfectHelloworld | ( _´U`_ ) | generator! | /___A___\ '--------------------------' | ~ | __'.___.'__ ´ ` |° ´ Y ` ? Would you like to enable this option? Yes method 1 just ran method 2 just ran create package.json create bower.json create .editorconfig create .jshintrc I'm all done. Running bower install & npm install for you to install the required dependencies. If this fails, try running the command yourself. npm WARN package.json package@0.0.0 No description npm WARN package.json package@0.0.0 No repository field. npm WARN package.json package@0.0.0 No README data $
次にアプリケーションで使う index.html を付け加えます。templates ディレクトリの中に indexhtmlファイルを登録します。ファイルの内容は
<html> <head> <title><%= title %></title> </head> </html>
index.js の writing に次のロジックを追加します
this.fs.copyTpl( this.templatePath('index.html'), this.destinationPath('app/index.html'), { title: 'Templating with Yeoman' } );
そうすると全体では
'use strict'; var yeoman = require('yeoman-generator'); var chalk = require('chalk'); var yosay = require('yosay'); module.exports = yeoman.generators.Base.extend({ initializing: function () { this.pkg = require('../package.json'); }, method1: function () { console.log('method 1 just ran'); }, method2: function () { console.log('method 2 just ran'); }, prompting: function () { var done = this.async(); // Have Yeoman greet the user. this.log(yosay( 'Welcome to the perfect' + chalk.red('Helloworld') + ' generator!' )); var prompts = [{ type: 'confirm', name: 'someOption', message: 'Would you like to enable this option?', default: true }]; this.prompt(prompts, function (props) { this.someOption = props.someOption; done(); }.bind(this)); }, writing: { app: function () { this.fs.copy( this.templatePath('_package.json'), this.destinationPath('package.json') ); this.fs.copy( this.templatePath('_bower.json'), this.destinationPath('bower.json') ); this.fs.copyTpl( this.templatePath('index.html'), this.destinationPath('app/index.html'), { title: 'Templating with Yeoman' } ); }, projectfiles: function () { this.fs.copy( this.templatePath('editorconfig'), this.destinationPath('.editorconfig') ); this.fs.copy( this.templatePath('jshintrc'), this.destinationPath('.jshintrc') ); } }, install: function () { this.installDependencies({ skipInstall: this.options['skip-install'] }); } });
これを実行すると appディレクトリ内にindex.htmlファイルが作成されます。できたhtmlは
<html> <head> <title>Templating with Yeoman</title> </head> </html>
最後に
generator-generatorを使ってオリジナルジェネレータを作るのも良いかと思います(既存のジェネレータをカスタマイズするのも良いかと)。残りのアドベントカレンダーではこのgenerator-generatorについて記載していきたいと考えております。