- 目次
- generator-generator
- 雛形を作る
- yo コマンドに認識させる(パスを通す)。
- yo my generator
- ファイルのコピーをする
- 選択肢を作ってみる
- 選択肢の結果でモジュールをインストールする
- bower
- npm
- 設定を保存してみる
- yo my subgenerator
- subgeneratorを作ってみる
- 設定を引き継いでsubgeneratorを動かしてみる。
- generator-generator
まず、node, yeoman シリーズが入っていることが前提条件です。
まず、以下のコマンドでgenerator-generatorをインストールします。
npm i -g generator-generator
まずは、generatorフォルダを作ります。
mkdir generator-sample
sample
の部分は好きな名前で構いません、ジェネレータの名前になります。
以下のコマンドでgeneratorの雛形が作成されます。
yo generator
最初に作成者名を聞かれるので適当に答えます。
2番目にジェネレータの名前を聞かれます。
デフォルトではgenerator-sample
のsample
部分が名前になります。
すると、以下のようなフォルダが作成されます。
./generator-sample
├── README.md
├── app
│ ├── index.js
│ └── templates
│ ├── _bower.json
│ ├── _package.json
│ ├── editorconfig
│ └── jshintrc
├── node_modules
├── package.json
└── test
├── test-creation.js
└── test-load.js
yoコマンドは以下のステップでgeneratorを認識しています。
- パスが通っているフォルダを総なめする。
node_modules
内のgenerator-
で開始されるフォルダを探すgenerator-
フォルダ内のapp/index.jsを実行する。
そのため、パスが通っている場所に、先程作成したgenerator-sample
のパスを通せば認識されます。
Mac,Linuxの場合はシンボリックリンク ln -s [generator-sampleフォルダ絶対パス] generator-sample
でnode_modules
へシンボリックリンクを作成します。
Windowsの場合はgenerator-sampleフォルダにパスを通すか、パスが通っているフォルダにgenerator-をコピーして下さい。
Windowsのnode_modules
のパスはC:\Users\ユーザー名\AppData\Roaming\npm\node_modules
です。
では早速generatorを実行してみましょう
新たにフォルダを作成し、そのフォルダの中で以下のコマンドを実行して下さい。
yo sample
パスが通って入れば、問題なくジェネレータが起動します。
適当に質問に答え、実行が完了すると以下のような新規プロジェクトが作成されます。
.
├── app
│ └── templates
├── bower.json
└── package.json
先程ジェネレーターを作成していると、質問が来ていたと思います。
generator内のapp/index.js
の以下の部分が、その質問を作成している部分です。
var prompts = [{
type: 'confirm',
name: 'someOption',
message: 'Would you like to enable this option?',
default: true
}];
ここに選択肢を追加してみましょう。
どのような質問が作成可能か知りたい場合はここのサイトを参考にしてください。
var prompts = [{
type: 'confirm',
name: 'coffee',
message: 'coffee scriptは使いますか?',
default: false
},
{
type: 'input',
name: 'yourname',
message: 'あなたの名前は?',
default: "someuser"
},
{
type: 'checkbox',
name: 'bower',
message: 'JavaScriptライブラリは何を使いますか?',
choices: [{
value: 'bootstrap',
name: 'twitter-bootstrap',
checked: false
},{
value: 'angularjs',
name: 'angular.js',
checked: false
}]
},
{
type: 'list',
name: 'cimodule',
message: 'CIツールは何を使いますか?',
choices: [{
value: 'gulp',
name: 'gulp.js',
checked: false
},{
value: 'grunt',
name: 'Grunt',
checked: false
}]
}];
選択肢を追加したのち、generatorの変数に選択肢の結果を格納させます。
this.prompt(prompts, function (props) {
var haslib = function (lib) { return props.bower.indexOf(lib) !== -1; };
var hasci = function (lib) { return props.cimodule.indexOf(lib) !== -1; };
this.include = this.include || {};
this.coffee = props.coffee;
this.yourname = props.yourname;
this.include.angular = haslib('angularjs');
this.include.bootstrap = haslib('bootstrap');
this.include.gulp = hasci('gulp');
this.include.grunt = hasci('grunt');
done();
}.bind(this));
選択肢で選んだ回答にあわせ、生成されるテンプレートを切り替えなければいけません。
bower、grunt/gulpを選択肢に合わせてインストールするように改変してみましょう。
app/templates/_bower.json
を開いて、以下のように編集します。
- 編集前
{
"name": "package",
"version": "0.0.0",
"dependencies": {}
}
- 編集後
{
"name": "package",
"version": "0.0.0",
"dependencies": {<% if (include.angular) { %>
"angular": ">=1.2.14",<% } if (include.bootstrap) {%>
"bootstrap": ">=3.1.1",<% } %>
"jquery": ">=2.1.0"
}
}
CIツールに合わせ、app/templates/_package.json
を編集してgrunt/gulpを選択出来るようにします。
- 編集前
{
"name": "package",
"version": "0.0.0",
"dependencies": {}
}
- 編集後
{
"name": "package",
"version": "0.0.0",
"dependencies": {<% if (include.grunt) { %>
"grunt": ">=0.4.4",<% } if (include.gulp) {%>
"gulp": ">=3.5.5",<% } %>
"jshint-stylish": ">=0.1.5"
}
}
ここまで編集したら、新しいフォルダを作るか、前のテンプレートを削除するかして、もう一度ジェネレートしてみましょう。
選択肢の内容に合わせ、javascriptライブラリやgrunt/gulpがインストールされれば成功です。
generatorにはsubgeneratorと言う考えがあります。
代表的な例は以下です。
このgeneratorは、テンプレート生成後に、同じフォルダ内で yo angular:route hoge
のように実行すると、
route
フォルダ内のindex.jsが実行されます。
route/index.js
では内部でviewとcontrollerを生成し、それを紐付けるrouterの追加を行ってくれます。
このように、プロジェクト生成後もルールに則った規則である程度の機能追加、改変を行うようにすることができます。
作成方法はgenerator-generator
で、以下のコマンドを実行します。
yo generator:subgenerator subgen
サブジェネレータ名(今回は仮にsubgen)を決めると、以下のようなフォルダ構成になります。
.
├── README.md
├── app
│ ├── index.js
│ └── templates
│ ├── _bower.json
│ ├── _package.json
│ ├── editorconfig
│ └── jshintrc
├── node_modules
├── package.json
├── subgen
│ ├── index.js
│ └── templates
│ └── somefile.js
└── test
├── test-creation.js
└── test-load.js
作成されたのち、新しいフォルダもしくは一度もう一度yo sample
を実行、その後yo sample:subgen hoge
と実行してみましょう。
フォルダにsomefile.js
がコピーされれば成功です。
今回、最初の選択肢にcoffee scriptの選択肢を入れました。
その最初の設定に紐subgeneratorを起動させるため、generatorの設定を保持、取得する機能を導入してみましょう。
generatorの設定の保持/取得は以下の機能を使います。
設定を保存する場合はthis.config.set();
を使用します。
以下のように記述することで、generator生成時に設定されたcoffee scriptのフラグが.yo-rc
ファイルに保存されるようになります。
this.prompt(prompts, function (props) {
var haslib = function (lib) { return props.bower.indexOf(lib) !== -1; };
var hasci = function (lib) { return props.cimodule.indexOf(lib) !== -1; };
this.include = this.include || {};
this.coffee = props.coffee;
this.yourname = props.yourname;
this.include.angular = haslib('angularjs');
this.include.bootstrap = haslib('bootstrap');
this.include.gulp = hasci('gulp');
this.include.grunt = hasci('grunt');
this.config.set('coffeescript', this.coffee); // <-- ここに追加!!
done();
}.bind(this));
合わせて、somefile.js
をコピーしてsomefile.coffee
を作成します。
generatorテンプレート作成時に保存された.yo-rc
の値はthis.config.get()
で取得することが出来ます。
subgen/index.js
の内容を以下の用に編集します。
generatorテンプレート作成時に選ばれたcoffee scriptの値により、somefile.js
とsomefile.coffee
のどちらかをコピーするという処理を追加します。
'use strict';
var util = require('util');
var yeoman = require('yeoman-generator');
var SampleGenerator = yeoman.generators.NamedBase.extend({
init: function () {
console.log('You called the sample subgenerator with the argument ' + this.name + '.');
this.coffee = this.config.get('coffeescript');
console.log('this.coffee',this.coffee);
},
files: function () {
console.log('this.name',this.name);
var fileext = (this.coffee?".coffee":".js");
var copyScript = this.name + fileext;
this.copy('somefile' + fileext, copyScript);
}
});
module.exports = SampleGenerator;
また最初からgeneratorを実行すると、最初に選択された設定に紐づき、ジェネレータが生成されるようになります。
以上で今回のハンズオンの内容は終了です、以下に参考ドキュメントなどをおいてますので
これから色々いじってみましょう。