2015/01/06

AngularJSのConceptual Overview

AngularJSの機能やコンセプトなどよくわかってないので、公式サイトのガイドを読んでいる。そこには、Conceptual Overviewなる一覧があり、例えばAngularJSのFilterとかわかっていない僕には嬉しい一覧であった。ので、自分の備忘録としてここに訳しつつ纏めておく。

Template
追加のマークアップを持つHTML
Directives
カスタム属性、カスタム要素を持つHTMLの拡張
Model
ユーザがView上で見たり操作するデータ
Scope
モデルが格納されるコンテキスト。controller、directive、expressionからアクセスできる。
Expressions
Scopeからアクセスする変数や関数を記述する式
Compiler
Templateを解析し、directiveやexpressionsをインスタンス化する。
Filter
式の値をユーザに見せるために整形する。
View
ユーザが目にするもの。
Data Binding
Model-View間でデータを同期する。
Controller
Viewの裏側のビジネスロジック。
Dependency Injection
オブジェクトと関数を生成し、結び付ける。
Injector
DIコンテナ
Module
Injectorを構成するcontroller、service、filter、directiveなどアプリの異なるパーツのためのコンテナ。
Service
Viewから独立した再利用可能なビジネスロジック

2015/01/04

YeomanのAngularJS Full-Stack generatorが提供するジェネレータ

AngularJS Full-Stack generatorは、アプリケーションのひな形だけでなく、アプリケーションの中身を開発する上で使えるジェネレータをいくつか提供しているってことに気づいたので纏めてみます。

angular-fullstack

アプリケーションそのものを作るジェネレータ。angular-fullstack:appのエイリアス。

$ yo angular-fullstack

これ以外のジェネレータには、サーバサイドの機能を作るためのジェネレータと、クライアントサイドの機能を作るためのジェネレータ、そしてデプロイのためのジェネレータがある。

サーバサイド

angular-fullstack:endpoint

REST APIのエンドポイントを生成するジェネレータ。例えば、issueというリソースに対するREST APIのエンドポイントを定義する場合は、

$ yo angular-fullstack:endpoint issue
を実行する。すると、
? What will the url of your endpoint to be? /api/v1/issues
   create server/api/issue/index.js
   create server/api/issue/issue.controller.js
   create server/api/issue/issue.model.js
   create server/api/issue/issue.socket.js
   create server/api/issue/issue.spec.js
となる。URLをどうするか聞かれるので、/api/v1/issuesと入力した。モデルやコントローラ、specファイルが生成される。

クライアントサイド

angular-fullstack:route

あるURLに対するクライアントサイドのリソース一式を生成するジェネレータ。例えば、/issuesというURLを有効にするために、

$ yo angular-fullstack:route issues
を実行すると、
? Where would you like to create this route? client/app/
? What will the url of your route be? /issues
   create client/app/issues/issues.js
   create client/app/issues/issues.controller.js
   create client/app/issues/issues.controller.spec.js
   create client/app/issues/issues.jade
   create client/app/issues/issues.less
が得られる。

angular-fullstack:controller

クライアントサイドのコントローラを生成する。

$ yo angular-fullstack:controller chat
を実行すると、
? Where would you like to create this controller? client/app/
   create client/app/chat/chat.controller.js
   create client/app/chat/chat.controller.spec.js
が得られる。

angular-fullstack:directive

AngularJSのdirectiveを生成する。何らかのチャートを表示するためのディレクティブを作るとして、

$ yo angular-fullstack:directive chart
を実行すると、
? Where would you like to create this directive? client/app/
? Does this directive need an external html file? Yes
   create client/app/chart/chart.directive.js
   create client/app/chart/chart.directive.spec.js
   create client/app/chart/chart.jade
   create client/app/chart/chart.less
が得られる。

angular-fullstack:filter

filterって何だろう。AngularJS初心者なのでまだ知りません。 でも、

$ yo angular-fullstack:filter someFilter
を実行すると、filterのためのファイルを生成してくれる、と。

angular-fullstack:service

AngularJSのserviceを生成する。 例えば、issueというリソースに関するAPIを提供するサービスを作るとして、

$ yo angular-fullstack:service issue
を実行すると、
? Where would you like to create this service? client/components
   create client/components/issue/issue.service.js
   create client/components/issue/issue.service.spec.js
が得られる。同様に、angular-fullstack:factoryangular-fullstack:providerというgeneratorも存在していて、それぞれ、
// yo angular-fullstack:service issue
'use strict';

angular.module('teamApp')
  .service('issue', function () {
    // AngularJS will instantiate a singleton by calling "new" on this function
  });
// yo angular-fullstack:factory issue
'use strict';

angular.module('teamApp')
  .factory('issue', function () {
    // Service logic
    // ...

    var meaningOfLife = 42;

    // Public API here
    return {
      someMethod: function () {
        return meaningOfLife;
      }
    };
  });
// yo angular-fullstack:provider issue
'use strict';

angular.module('teamApp')
  .provider('issue', function () {

    // Private variables
    var salutation = 'Hello';

    // Private constructor
    function Greeter() {
      this.greet = function () {
        return salutation;
      };
    }

    // Public API for configuration
    this.setSalutation = function (s) {
      salutation = s;
    };

    // Method for instantiating
    this.$get = function () {
      return new Greeter();
    };
  });
を生成する。

angular-fullstack:decorator

公式サイトには

Generates an AngularJS service decorator.
とあるが、これもよくわかっていない。が、
yo angular-fullstack:decorator issue
を実行すると、
? Where would you like to create this decorator? client/components
   create client/components/issue/issue.decorator.js
が得られ、
'use strict';

angular.module('teamApp')
  .config(function ($provide) {
    $provide.decorator('issue', function ($delegate) {
      // decorate the $delegate
      return $delegate;
    });
  });
が生成された。

デプロイ

デプロイのためのgeneratorとしては、

  • yo angular-fullstack:openshift
  • yo angular-fullstack:heroku
があって、それぞれOpenShift、Herokuへのデプロイを簡単に行うためのコマンドのようだが、今回は割愛。

終わりに

filterや、service decoratorなどAngularJSを理解していないと使い方がわからないものがあり、使いこなすにはもっと勉強しないと、と感じた。あとは、クライアントサイドのディレクトリ構成を意識するというか、戦略を持たないといけないな。

2015/01/01

YeomanでAngularJS、Express、MongoDB、Node.jsなアプリのひな形を作る。

Yeomanを使ってMEAN(MongoDB、Express、AngularJS、Node.js)なWebアプリケーションのひな形を作ってみます。

AngularJS Full-Stack generator

AngularJS Full-Stack generatorというgeneratorを使用する。

$ npm install -g generator-angular-fullstack
でインストールする。-gオプションを付けてglobalなパッケージとしてインストールする。

AngularJS Full-Stackを実行する。

$ yo angular-fullstack
を実行すると、generatorが次のような質問をしてくるので、適宜答えてあげる。
  • JavaScript、CoffeeScriptのどっちを使う?
  • HTMLとJade、どっちでマークアップする?
  • css、sass、stylus、lessのどれでスタイル書く?
  • AngularのRouterは、ngRouterとuiRouterのどっちを使う?
  • Twitter Bootstrap使う?
  • ui-bootstrapを使う?
  • MongoDBのモデリングにはmongooseを使う?
  • 認証処理のboilerplateを生成する?
  • Google、Facebook、TwitterのOAuthストラテジを有効にする?
  • socket.ioを使う?
質問に答えていくと↑のような画面になる。ここから先は、npm installとかbower installとかYoermanが自動で進めてくれる。

生成したプロジェクト

このgeneratorによって生成したプロジェクトは↓のようなディレクトリ構造になる。

.
├── Gruntfile.js
├── bower.json
├── client
├── e2e
├── karma.conf.js
├── node_modules
├── package.json
├── protractor.conf.js
└── server
clientディレクトリにはクライアントサイドのコードを、serverディレクトリにはサーバサイドのコードを格納するっていうのが、以前のバージョンから変わったところか。e2eディレクトリの目的は詳細を調べる必要がある。

アプリケーションを起動する。

$ grunt serve
でアプリケーションが起動する。

2014/12/30

mean-cliでアプリケーションのひな形を作る。

mean-cliを使ってアプリケーションのひな形を作るまでの手順を纏めてみます。

準備

NodeJS、MongoDB、Git

前提として、NodeJS、MongoDB、Gitが必要。それぞれインストールしておく。 ここでは詳細は割愛。

npmのバージョンを上げておく。

npmのバージョンが2.xでないとWARNINGが出るので、上げておく。

$ npm update -g npm
を実行する。

Grunt.jsあるいはGulp.jsをインストールしておく

meanで作成するプロジェクトは、タスクマネージャとしてGruntかGlupを選択できる。デフォルトはGrunt。両方入れておく。

$ npm install -g grunt-cli gulp

mean-cliをインストールする。

インストールするのは、mean-cli。なので、

$ npm install -g mean-cli
を実行する。

mean-cliを使ってプロジェクトを作る。

インストールしたmean-cliを使って、Webアプリケーションプロジェクトを作成する。例えば、teamというプロジェクトを作るには、

$ mean init team
を実行する。すると、アプリケーション名と利用するタスクマネージャ(GruntかGulpか、僕はGulpを選択)を問われ、答えるとプロジェクトディレクトリを生成してくれる。

npmパッケージのインストール

生成されたプロジェクトのルートに移動し、npm installを実行する。

$ cd /path/to/team
$ npm install

アプリケーションの起動

アプリケーションを起動してみる。Gulpを使うよう指示したので、gulpのデフォルトタスクを起動するとアプリケーションが起動する。

$ gulp
そして、http://localhost:3000にアクセスすると、↓のような画面が表示される。

ヘッダの「Join」リンクをつつくと、ユーザ登録ページに遷移する。

また、「Log in」リンクをつつくとログインページに遷移する。

初めてmean-cliを使って、アプリケーションのひな形を作るところまでやってみました。 これから実際に何か作ってみます。ちなみに、あのキャラクターは、Daphneっちゅー忍者らしいですね。JenkinsとかYeomanとかキャラがおっさんだったから、ちょっと可愛いなと思いました。どうでもいいですけど。

2014/11/20

PM2でnodeなWebアプリをデプロイしてみた

npmにPM2というプロセスマネージャツールがあって、プロセスの起動、終了、監視などを便利に行ってくれる。実はPM2にはアプリのデプロイもできちゃうことを知ったので試してみました。

デプロイのフロー

基本的なフローは、PM2/ADVANCED_README.md at development · Unitech/PM2に書いてあるとおりで行けましたんで、流れを纏めておこうと思います。

ecosystem

PM2でデプロイしたいアプリケーションや、デプロイ先の情報は、jsonファイルに記述します。そのファイルのひな形を作るコマンドが、

$ pm2 ecosystem
です。このコマンドを叩くと、↓のようなファイルが生成されます。こいつを自分の環境に合わせて編集します。
{
  "apps" : [{
    "name"      : "API",
    "script"    : "app.js",
    "env": {
      "COMMON_VARIABLE": "true"
    },
    "env_production" : {
      "NODE_ENV": "production"
    }
  },{
    "name"      : "WEB",
    "script"    : "web.js"
  }],
  "deploy" : {
    "production" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "ref"  : "origin/master",
      "repo" : "git@github.com:repo.git",
      "path" : "/var/www/production",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env production"
    },
    "dev" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "ref"  : "origin/master",
      "repo" : "git@github.com:repo.git",
      "path" : "/var/www/development",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env dev"
    }
  }
}

setup

デプロイ先にsshで接続し、アプリケーション格納ディレクトリを掘ったり何やらかんやらするコマンドが、

$ pm2 deploy ecosystem.json production setup
です。上述のecosystem.jsonを指定してdeployのsetupを行います。このままだと、デプロイ先のサーバに対して、22ポートを指定してsshで接続にいきます。sshのポート番号を指定するには、ecosystem.jsonに追記します。
{
  "apps" : [{
    "name"      : "API",
    "script"    : "app.js",
    "env": {
      "COMMON_VARIABLE": "true"
    },
    "env_production" : {
      "NODE_ENV": "production"
    }
  },{
    "name"      : "WEB",
    "script"    : "web.js"
  }],
  "deploy" : {
    "production" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "ref"  : "origin/master",
      "repo" : "git@github.com:repo.git",
      "path" : "/var/www/production",
      "port" : 99999, // sshポート番号
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env production"
    },
    "dev" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "ref"  : "origin/master",
      "repo" : "git@github.com:repo.git",
      "path" : "/var/www/development",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env dev"
    }
  }
}
実際にsetupが成功すると、ecosystem.jsonで指定したpath配下に、次のようなディレクトリが作成されます。
foo@bar:/var/www/production$ ls -la
total 20
drwxrwxr-x  4 root root 4096 Nov 20 00:48 .
drwxrwxr-x  5 root root 4096 Nov 20 00:48 ..
-rw-rw-r--  1 node node   48 Nov 20 00:12 .deploys
lrwxrwxrwx  1 node node   20 Nov 20 00:12 current -> /var/www/production/source
drwxrwxr-x  4 node node 4096 Nov 14 00:57 shared
drwxrwxr-x 12 node node 4096 Nov 19 00:03 source

deploy

実際にデプロイするのは、

$ pm2 deploy ecosystem.json production
のコマンドです。これにより、リポジトリからのチェックアウトがなされ、ecosystem.jsonのpost-deployに指定したコマンドを実行します。デフォルトのecosystem.jsonではpm2によるプロセスの起動or再起動を行うコマンドが指定されています。例えば、npmやbowerのパッケージのインストール後に、nodeプロセスの再起動を、という場合は、↓のように書いてできました。
{
  : (省略)
  "post-deploy" : "npm install && bower install && pm2 startOrRestart ecosystem.json --env production"
  : (省略)
}

その他

pm2のデプロイ関連のコマンドを実行すると、/tmp/pm2-deploy.log にログが出力されます。ssh経由で発行したコマンドなども記録されますんで、デバッグやら何やらに参照するとよさそうです。