Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

やはり俺のYeomanはまちがっている。

最近「筋トレ」で身体を追い込んでる「僧職系エンジニア」です。

以前、社内勉強会でGruntについて発表させて頂いた所

お髭の錬金術士「Yeomanもよろしくです、blogで^^」
二次元エンジニア「ネタいれるなら、やりきってください^^」

とネタ振り及びありがたいFBを頂きましたので今回はYeomanを題材にすることにしました。

Yeomanとは?

開発のためのワークフローを提供してくれます。
とは言っても何がなにやらですね。
YeomanはYoBowerGruntの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

必要なものをインストールする

とりあえずYoBowerGruntがないと話にならないので、この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はまちがっている。