最近「筋トレ」で身体を追い込んでる「僧職系エンジニア」です。
以前、社内勉強会でGruntについて発表させて頂いた所
お髭の錬金術士「Yeomanもよろしくです、blogで^^」
二次元エンジニア「ネタいれるなら、やりきってください^^」
とネタ振り及びありがたいFBを頂きましたので今回はYeomanを題材にすることにしました。
Yeomanとは?
開発のためのワークフローを提供してくれます。
とは言っても何がなにやらですね。
YeomanはYo、Bower、Gruntの3つでなりたっており、それぞれ役割が違います。
Yo
scaffoldingを提供するツール
用は雛形作りまっせーってことですね。
Bower
クライアントライブラリ管理ツール
bower install hogehogeでjquery等色んなライブラリをインストール出来ます。
まぁインストールって言ってもgitからcloneしてくるだけです。
Grunt
ビルドツール
jsの圧縮や結合、cssの圧縮、ファイルの監視など色んな事が出来ます。
これらを組み合わせたものがYeomanとなります。
今回はこれらの細かい設定方法などは省きますが、色々出来ちゃいますよ
今回のゴール
ただ闇雲に各機能を紹介しても面白く無いので今回はゴールを設定します。
Yeomanを使用して以下のルールに則った雛形を作成してみましょう。
- 新しくプロジェクト作る際に特定のフォルダ構成にしたい
- 共通で使うJSを統一する
- JSの圧縮/結合、CSSの圧縮が出来る
- 雛形の名前は比企谷にしたい
フォルダ構成は以下をイメージしてます。
├── app │ └── controller │ └── model │ └── view └── public │ └── assets │ └── js │ │ ├── lib // 共通のライブラリ => bowerでinstall │ │ ├── dev │ │ ├── prod │ └── css │ │ ├── dev │ │ ├── prod │ └── img └── Gruntfile.js └── bower.json └── bower_components └── node_modules └── package.json
必要なものをインストールする
とりあえずYo、Bower、Gruntがないと話にならないので、この3つと
後ほど使用するgenerator-generatorをインストールします。
npm install -g yo bower grunt-cli generator-generator
generatorの雛形を作成し、実際に使えるようにする
雛形作成にはgeneratorを使用するので、まずはgenerator-hikigayaを作成します。
$ mkdir generator-hikigaya && cd $_ $ yo generator
実行すると比企谷が出てきて色々聞くので回答してください。
婚活ポータルサイト「静」を作成すると想定して ディレクトリを作ってその中で作成した雛形へリンクを張ります。
$ mkdir shizuka && cd $_ $ mkdir node_modules $ ln -s <node_modulesからのgenerator-hikigayaのpath> node_modules/.
これで準備は整いましたので実行してみましょう。
$ yo hikigaya
これでshizukaフォルダ以下にgenerator-hikigayaのデフォルトの構成が作られます。 ではここからゴールに向かって走りましょう。
generator-hikigayaをカスタマイズしてフォルダ構成を整えるよ
今のままだとhikigayaが万人受けしないので、万人受けするようにフォルダ構成を変更しましょう。 何事も引き出しが多いほうがモテますしね。
generator-hikigaya/app/index.js内部のHikigayaGenerator.prototype.appに処理を記述します。
$ vi generator-hikigaya/app/index.js
HikigayaGenerator.prototype.app = function app() { this.mkdir('app'); this.mkdir('app/controller'); this.mkdir('app/model'); this.mkdir('app/view'); // こんな感じでディレクトリ作成します。 this.mkdir('public'); this.mkdir('public/assets'); this.mkdir('public/assets/js'); this.mkdir('public/assets/js/lib'); this.mkdir('public/assets/js/dev'); this.mkdir('public/assets/js/prod'); this.mkdir('public/assets/css'); this.mkdir('public/assets/css/dev'); this.mkdir('public/assets/css/prod'); this.mkdir('public/assets/img'); this.copy('_package.json', 'package.json'); this.copy('_bower.json', 'bower.json'); };
これでフォルダ構成の変更はおしまいです。
次はgruntの設定を行います。
package.jsonを変更してgruntのpluginを入れちゃうよ
JSの圧縮と結合、CSSの圧縮をやりたいので
generator-hikigaya/app/templates以下の_package.jsonを編集します。
それとgruntのbower用pluginも入れておきます。
これに関しては後ほど説明します。
{ "name": "package", "version": "0.0.0", "dependencies": {}, "devDependencies": { "grunt": "~0.4.2", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-uglify": "~0.2.7", "grunt-contrib-cssmin": "~0.7.0", "grunt-bower-task": "~0.3.4" } }
続いて今回の用途に見合ったGruntfile.jsを作成します。
Gruntfile.jsを編集して色々出来るようにしちゃうよ
やりたいことは
- JSを結合・圧縮してprodに配置
- cssを圧縮してprodに配置
- bowerでライブラリをインストールした際に無駄なものをなくす&フォルダ構成をフラットにする
です。
Gruntfile.jsはgenerator-hikigaya/app/templates/に配置します。
$ generator-hikigaya/app/templates/Gruntfile.js
module.exports = function(grunt) { grunt.initConfig({ concat: { dev:{ src:['public/assets/js/dev/**/*.js'], dest: 'public/assets/js/prod/app.js' } }, uglify: { dist:{ files:{ 'public/assets/js/prod/app.min.js':['public/assets/js/prod/app.js'] } } }, cssmin: { minify_base: { expand: true, cwd: 'public/assets/css/dev/', src: ['*.css', '!*.min.css'], dest: 'public/assets/css/prod/', ext: '.min.css' } }, bower: { install: { options:{ // bowerのライブラリを綺麗に入れるための設定 targetDir:'public/assets/js/lib', layout:'byComponents', install:true, verbose:false, cleanTargetdir:true, cleanBowerDir:false } } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-bower-task'); grunt.registerTask('default',['concat', 'uglify', 'cssmin']); grunt.registerTask('js', ['concat', 'uglify']); grunt.registerTask('css', ['cssmin']); };
これでGruntfile.jsの設定は終わりです。
これをgenerator実行時にcopyするよう
generator-hikigaya/app/index.js内部のHikigayaGenerator.prototype.appに処理を変更します。
$ vi generator-hikigaya/app/index.js
HikigayaGenerator.prototype.app = function app() { this.mkdir('app'); this.mkdir('app/controller'); this.mkdir('app/model'); this.mkdir('app/view'); this.mkdir('public'); this.mkdir('public/assets'); this.mkdir('public/assets/js'); this.mkdir('public/assets/js/lib'); this.mkdir('public/assets/js/dev'); this.mkdir('public/assets/js/prod'); this.mkdir('public/assets/css'); this.mkdir('public/assets/css/dev'); this.mkdir('public/assets/css/prod'); this.mkdir('public/assets/img'); this.copy('_package.json', 'package.json'); this.copy('_bower.json', 'bower.json'); // 追加 this.copy('Gruntfile.js', 'Gruntfile.js'); };
長かったですね。。。もう少しなので頑張りましょう。
次はbowerの設定です。
Bowerをカスタマイズしてライブラリを突っ込むよ
assets/js以下のlibに共通で使うライブラリを入れるようにします。
generator-hikigaya/app/templates以下の_bower.jsonを編集して
jquery、fastclick、mustasheを取り込んでみましょう。
尚、Bowerはgitからcloneしてくるだけなので、そのままだと不要なファイルが入っていたり
フォルダ構成が綺麗になりません。
ですから今回は「grunt-bower-task」を使用してます。
{ "name": "package", "version": "0.0.0", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "jquery": "~2.0.3", "fastclick": "~0.6.10", "mustache": "https://github.com/janl/mustache.js.git" }, // grunt-bower-task用の設定 "exportsOverride":{ "mustache":{ "js": "**/*.js" } } }
これで準備は整いましたので、実際にやってみます。
yoを使って再度プロジェクトを作ってみるよ
次は 男装喫茶ポータルサイト「彩加」 を作成すると想定して、前と同じ手順を実行します。
$ mkdir saika && cd $_ $ mkdir node_modules $ ln -s <node_modulesからのgenerator-hikigayaのpath> node_modules/. $ yo hikigaya
これでフォルダ構成及び必要なGrunt、Bowerの設定は出来ました。 ただ、まだassets/js/lib以下にBowerで管理しているjsが入っていません。 最後の仕上げに以下のコマンドを叩きます。
$ grunt bower:install
これでassets/js/lib以下にBower管理下のjsが綺麗に入ったはずです。
雛形を作って見た結果
今回の流れで汎用的な雛形「比企谷」が出来ました。 もしこれから お嬢様学校ポータルサイト「雪乃」 アホっ子ポータルサイト「結衣」 などなど、複数サイトを量産する場合でも、どれも同じ構成からスタートすることが出来ます。
今回やったのはまだ序章でしたが、これだけでも開発の効率はあがりますね。
どっかからコピーして色々やらなくて済みますし。
プロジェクトで使うならgeneratorを社内gitなどに突っ込むといいかもですね。
最後に一連の流れをまとめてみた
Yeomanを使うと共通で使用するの雛形を作成することが出来る | 雛形を使用すると各プロジェクトを開始するときに、
意図した構成で開始出来る。 | ただし、汎用的な雛形(テンプレート)に頼りすぎると
だんだんと情熱がなくなってくる | その結果、本命(個性的なサイト)が出来なくなる。 | だから僕は、彼女が出来ない。 | やはり俺の(リアル)Yeomanはまちがっている。