そんな今日この頃でして、、、

コード書いたり映画みたり。努力は苦手だから「楽しいこと」を探していきたい。

Yeomanのチュートリアルの個人的なまとめ

前年末の予告通りYeomanのチュートリアルをやってみたので、そのまとめ。

Let's Scaffold a Web App with Yeoman | Yeoman

公式ページのチュートリアル手順は結構親切に書いてはあるが、何点か引っかかるところがあったのでその辺も。

ちなみに今回やってみた際の各バージョン↓

version
yo 1.3.3
grunt-cli 0.1.13
bower 1.3.12


Yeomanとは?

大雑把にいえば、今時っぽいWebアプリ開発の基盤をよしなにしてくれるツールである。

The web's scaffolding tool for modern webapps | Yeoman

アプリのひな形を作ってくれるYo、ライブラリ管理をするBower、テストだのビルドだのを自動化してくれるGruntという3つのツールを統合したもの。


Yeoman導入

何はともあれ導入。

チュートリアル的にはStep1(Yeoman - Modern workflows for modern webapps)にあたる。

$ npm install -g yo bower grunt-cli


ジェネレータの導入

作りたいアプリに合うひな形のジェネレータを導入する。

チュートリアル的にはStep2(Yeoman - Modern workflows for modern webapps)の手順。

今回はAngularJSを用いるので↓

$ npm install -g generator-angular@0.9.2


ちなみに他のジェネレータなんかは

$ npm search yeoman-generator

で探せる。


ひな形の作成

Step3(Yeoman - Modern workflows for modern webapps)あたり。

とりあえず作業用のディレクトリを用意し、

$ mkdir mytodo && cd mytodo


yoコマンドでひな形を作成。

$ yo
? 'Allo *****! What would you like to do? Angular

Make sure you are in the directory you want to scaffold into.
This generator can also be run with: yo angular


     _-----_
    |       |    .--------------------------.
    |--(o)--|    |    Welcome to Yeoman,    |
   `---------´   |   ladies and gentlemen!  |
    ( _´U`_ )    '--------------------------'
    /___A___\
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

Out of the box I include Bootstrap and some AngularJS recommended modules.

? Would you like to use Sass (with Compass)? No
? Would you like to include Bootstrap? Yes
? Which modules would you like to include? angular-animate.js, angular-cookies.js, angular-resource.js, angular-route.js, angular-sanitize.js, angular-touch.js

現バージョンでは公式と表示がいくらか異なるが、そこはニュアンスで進めていけば良い。


正常に終了すると、作業ディレクトリに諸々のファイルが作成される。

Step4(Yeoman - Modern workflows for modern webapps)。

この中の主にappディレクトリ以下のファイルを編集して開発を進めていく感じになる。


Gruntを用いてひな形を確認する

Step5(Yeoman - Modern workflows for modern webapps)。

grunt serveコマンドによりnodeベースのhttpサーバが立ち上がるらしい。

ということで意気揚々と打ってみると・・・

$ grunt serve
Running "serve" task

Running "clean:server" (clean) task

Running "wiredep:app" (wiredep) task
Warning: ENOENT, no such file or directory '/Users/*****/mytodo/app/bower.json' Use --force to continue.

Aborted due to warnings.


Execution Time (2015-01-02 08:20:01 UTC)
loading tasks    4ms  ▇▇ 2%
clean:server     5ms  ▇▇ 2%
wiredep:app    201ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 94%
Total 213ms

あれ、bower.jsonのパスが違うとかで怒られる・・・

どうも作業ディレクトリ直下にあるはずのbower.jsonapp以下に見に行こうとしてしまってる模様。

ググった所grunt-wiredepというライブラリのバージョンに依存する問題らしい。

参考↓

YEOMANのチュートリアルでいきなりハマった人向け | mah365

作業フィルダ直下のGruntの動作に関わるGruntfile.jsのwiredep・options項のcmdをコメントアウトすればOK

    // Automatically inject Bower components into the app
    wiredep: {
      options: {
        //cwd: '<%= yeoman.app %>'
      },
      app: {
        src: ['<%= yeoman.app %>/index.html'],
        ignorePath:  /\.\.\//
      }
    },


意気揚々と再実行。

$ grunt serve
Running "serve" task

Running "clean:server" (clean) task

Running "wiredep:app" (wiredep) task
app/index.html modified.

Running "concurrent:server" (concurrent) task

    Running "copy:styles" (copy) task
    Copied 1 files

    Done, without errors.


    Execution Time (2015-01-02 08:25:09 UTC)
    loading tasks   4ms  ▇▇▇▇▇▇▇▇▇▇ 21%
    copy:styles    15ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 79%
    Total 19ms

Running "autoprefixer:dist" (autoprefixer) task
File .tmp/styles/main.css created.

Running "connect:livereload" (connect) task
Started connect web server on http://localhost:9000

Running "watch" task
Waiting...

ちゃんと動いた。

ブラウザからhttp://localhost:9000にアクセスすることでページを確認できる。


ちなみに./app/view/main.htmlが正に表示されてるページの見た目部分となるわけだが、サーバを立ち上げたままこのファイルを編集するとライブリロードされる(保存されたタイミングでブラウザ側も勝手に追従してくれる)。

地味に便利。


コーディング

Step6(Yeoman - Modern workflows for modern webapps)。

./app/views/main.htmlおよび./app/scripts/controllers/main.jsを編集してアプリ作成していく。

この辺はチュートリアルページをまんま写経すればOK。

予めAngularJSの基礎的な使い方を知ってると理解しやすいだろう。

(こういうチュートリアルで出てくるようになったあたりもはや業界標準感あるし、去年のうちにある程度使えるようになっておいてよかった。)

AngularJSリファレンス

AngularJSリファレンス


Bowerを用いてライブラリを追加する

Step7(Yeoman - Modern workflows for modern webapps)。

作業ディレクトリでbower listで現状を確認。

ひな形作成時に選択されたのが入っているはず。

$ bower list
bower check-new     Checking for new versions of the project dependencies..
mytodo#0.0.0 /Users/*****/mytodo
├── angular#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
├─┬ angular-animate#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
├─┬ angular-cookies#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-mocks#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-resource#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-route#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-sanitize#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-scenario#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-touch#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ bootstrap#3.1.1 (latest is 3.3.1)
│ └── jquery#2.1.3
├── es5-shim#3.1.1 (latest is 4.0.5)
└── json3#3.3.2


追加したいライブラリをインストール。

$ bower install --save angular-ui-sortable jquery-ui


再度確認。

$ bower list
bower check-new     Checking for new versions of the project dependencies..
mytodo#0.0.0 /Users/*****/mytodo
├── angular#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
├─┬ angular-animate#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
├─┬ angular-cookies#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-mocks#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-resource#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-route#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-sanitize#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-scenario#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-touch#1.2.16 (latest is 1.3.9-build.3744+sha.66ceecc)
│ └── angular#1.2.16
├─┬ angular-ui-sortable#0.13.1 extraneous
│ ├── angular#1.2.16 (1.3.9-build.3744+sha.66ceecc available)
│ └─┬ jquery-ui#1.11.2
│   └── jquery#2.1.3
├─┬ bootstrap#3.1.1 (latest is 3.3.1)
│ └── jquery#2.1.3
├── es5-shim#3.1.1 (latest is 4.0.5)
└── json3#3.3.2


実際のファイルなんかは./bower_componentsに追加される。

$ ls -1 bower_components/
angular
angular-animate
angular-cookies
angular-mocks
angular-resource
angular-route
angular-sanitize
angular-scenario
angular-touch
angular-ui-sortable
bootstrap
es5-shim
jquery
jquery-ui
json3


また、bower.jsonにも記述される。


一旦立ち上げてたhttpdサーバをCtrl+Cで終了し、grunt sarveで再度起動すると.app/index.htmlにも追記されることが確認できる。


追加されたライブラリをアプリで使用するために、./app/script/app.jsに追加を行う。

※ 最後に述べるが、本来はこの時config項の修正をするのが望ましいのかもしれない。

angular
  .module('mytodoApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.sortable'
  ])

またhtmlにも対応する記述を追加する。


テスト

Step8(Yeoman - Modern workflows for modern webapps)。

./test/karma.conf.jsに新たに追加されたライブラリの記述を加える。

また、実際のコードに合わせて./test/spec/controllers/main.jsのテスト要項を修正する。

あとはgrunt testコマンドでテストが走る。


余談だけど、このテストにはPhantomJSが使われている。

全く別件で勉強してた技術が、そうと意識せずに繋がる感じは面白い。

CasperJSで動的ページをスクレイピング、あるいは毎月100円ゲットする方法について - そんな今日この頃でして、、、


本番用のファイルを出力する

Step9(Yeoman - Modern workflows for modern webapps)。

実際のサーバに上げるためのファイルを出力する。

gruntコマンドで最適化その他諸々を行った後、grunt serve:distコマンドで./distディレクトリ内に出力&サーバ起動で動作確認できる。

問題なければ./distディレクトリ以下をもっていけばOK。


LocalStorage対応

Step10(Yeoman - Modern workflows for modern webapps)。

チュートリアルでは更にその後にブラウザに保存するLocalStorageの対応する手順が載っている。

が、ここがちょっと記載足りなかったりで引っかかりどころあった。


基本的には公式ページに従い追記していき、さらにテストに対応するために./test/karma.conf.js'bower_components/angular-local-storage/dist/angular-local-storage.js'を記述を追加する。

これでテストは通るようになる。


ここで、僕の環境だとgrunt serveで立ち上げてた時は問題ないのに、grunt serve:sidtで作成した方だと[$injector:modulerr]なるエラーが発生する。

ドンピシャな記事は見当たらなかったのでちょっと正確なところは分からないけど、雰囲気的にはminifyした後のコードではLocalStorageモジュールが加わったことによりngRouteモジュールが正しく読めてない感じなのだろうか?

参考↓

$routeProviderがない – AngularJS 1.2.0-rc にアップデートする際の注意 | ygoto3's caught up

モジュールの読み込みを行ってる./app/script/app.jsのconfigでrouteProviderを明示的にしてやることでとりあえず解消できた。

  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }]);



何かと面倒なテストのひな形まで作ってくれるのは実にありがたい。

僕はAltJSには手を出せてないが、そのへん使ってる人ならより便利に感じるんだろうなって気がする。

実用的には自分の使ってる環境に合わせてジェネレータを作成すると良いんだろうな。


ただ、僕はフロントは門外漢なせいか、こうやって作成したコードってどうバーション管理&デプロイしてくのがベターなのかイマイチわからなかった。



そういえば、我慢できずにマルチコプター買いました!

1万前後の価格帯では大きめで安定性のある↓を選択。

届いたタイミングが遅かったこともあって今日は外にはもっていけず、かといって室内で飛ばすには大きさ的に厳しくて、今のところ玄関前で浮かせてみる位しか遊べていないけれど、空物ラジコンで動画が撮れるのは超ワクワクする!