Webアプリケーションを作る入門的なジェネレータ generator-angular を紹介します。このエントリーは「YEOMAN Advent Calendar 2014」12月4日の記事です。
YEOMAN Advent Calendar 2014 - Adventar
ジェネレータ generator-angular は AngularJS を利用するためのものです。
インストールから実行まで
インストール
いつものようにジェネレータをインストールしてプロジェクトディレクトリを作りyoとgruntの実行です。
$ npm install -g generator-angular $ mkdir angular && cd $_ $ yo angular $ grunt serve
途中聞いてくるオプションは
- Sassを利用するか?
- Bootstrapを利用するか?
- AngularJSのモジュールはどれを使うか
です
? Would you like to use Sass (with Compass)? Yes ? Would you like to include Bootstrap? Yes ? Would you like to use the Sass version of Bootstrap? Yes ? Which modules would you like to include? (Press <space> to select) ❯◉ angular-animate.js ◯ angular-aria.js ◉ angular-cookies.js ◉ angular-resource.js ◯ angular-messages.js ◉ angular-route.js ◉ angular-sanitize.js ◉ angular-touch.js
実行
実行結果は次の通りです。
bower でインストールされているモジュールは次の通りです。
"angular": "^1.3.0", "json3": "^3.3.0", "es5-shim": "^4.0.0", "bootstrap-sass-official": "^3.2.0", "angular-animate": "^1.3.0", "angular-cookies": "^1.3.0", "angular-resource": "^1.3.0", "angular-route": "^1.3.0", "angular-sanitize": "^1.3.0", "angular-touch": "^1.3.0"
grunt タスクについては AngularですのでJavaScriptテスティングフレームワークが karma です。その他諸々あり:
"grunt": "^0.4.1", "grunt-autoprefixer": "^0.7.3", "grunt-concurrent": "^0.5.0", "grunt-contrib-clean": "^0.5.0", "grunt-contrib-compass": "^0.7.2", "grunt-contrib-concat": "^0.4.0", "grunt-contrib-connect": "^0.7.1", "grunt-contrib-copy": "^0.5.0", "grunt-contrib-cssmin": "^0.9.0", "grunt-contrib-htmlmin": "^0.3.0", "grunt-contrib-imagemin": "^0.8.1", "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-uglify": "^0.4.0", "grunt-contrib-watch": "^0.6.1", "grunt-filerev": "^0.2.1", "grunt-google-cdn": "^0.4.0", "grunt-karma": "^0.9.0", "grunt-newer": "^0.7.0", "grunt-ng-annotate": "^0.4.0", "grunt-svgmin": "^0.4.0", "grunt-usemin": "^2.1.1", "grunt-wiredep": "^1.7.0", "jasmine-core": "^2.1.3", "jshint-stylish": "^0.2.0", "karma-jasmine": "^0.3.2", "karma-phantomjs-launcher": "^0.1.4", "load-grunt-tasks": "^0.4.0", "time-grunt": "^0.3.1"
サブジェネレータ
YEOMANテンプレートのコマンドとして各コンポーネントを生成するサブジェネレータも用意されています:
yo angular:controller yo angular:directive yo angular:filter yo angular:route yo angular:service yo angular:provider yo angular:factory yo angular:value yo angular:constant yo angular:decorator yo angular:view
yo angular:controller
$ yo angular:controller controller create app/scripts/controllers/controller.js create test/spec/controllers/controller.js $
作成されるコントローラは次の通りです:
'use strict'; /** * @ngdoc function * @name angularApp.controller:ControllerCtrl * @description * # ControllerCtrl * Controller of the angularApp */ angular.module('angularApp') .controller('ControllerCtrl', function ($scope) { $scope.awesomeThings = [ 'HTML5 Boilerplate', 'AngularJS', 'Karma' ]; });
スペックについては次の通りです:
'use strict'; describe('Controller: ControllerCtrl', function () { // load the controller's module beforeEach(module('angularApp')); var ControllerCtrl, scope; // Initialize the controller and a mock scope beforeEach(inject(function ($controller, $rootScope) { scope = $rootScope.$new(); ControllerCtrl = $controller('ControllerCtrl', { $scope: scope }); })); it('should attach a list of awesomeThings to the scope', function () { expect(scope.awesomeThings.length).toBe(3); }); });
yo angular:directive
$ yo angular:directive directive create app/scripts/directives/directive.js create test/spec/directives/directive.js $
作成されるディレクティブは次の通りです:
'use strict'; /** * @ngdoc directive * @name angularApp.directive:directive * @description * # directive */ angular.module('angularApp') .directive('directive', function () { return { template: '<div></div>', restrict: 'E', link: function postLink(scope, element, attrs) { element.text('this is the directive directive'); } }; });
スペックについては次の通りです:
'use strict'; describe('Directive: directive', function () { // load the directive's module beforeEach(module('angularApp')); var element, scope; beforeEach(inject(function ($rootScope) { scope = $rootScope.$new(); })); it('should make hidden element visible', inject(function ($compile) { element = angular.element('<directive></directive>'); element = $compile(element)(scope); expect(element.text()).toBe('this is the directive directive'); })); });
yo angular:filter
$ yo angular:filter filter create app/scripts/filters/filter.js create test/spec/filters/filter.js $
作成されるフィルタは次の通りです:
'use strict'; /** * @ngdoc filter * @name angularApp.filter:filter * @function * @description * # filter * Filter in the angularApp. */ angular.module('angularApp') .filter('filter', function () { return function (input) { return 'filter filter: ' + input; }; });
スペックについては次の通りです:
'use strict'; describe('Filter: filter', function () { // load the filter's module beforeEach(module('angularApp')); // initialize a new instance of the filter before each test var filter; beforeEach(inject(function ($filter) { filter = $filter('filter'); })); it('should return the input prefixed with "filter filter:"', function () { var text = 'angularjs'; expect(filter(text)).toBe('filter filter: ' + text); }); });
yo angular:route
$ yo angular:route route create app/scripts/controllers/route.js create test/spec/controllers/route.js create app/views/route.html $
作成されるルータは次の通りです:
'use strict'; /** * @ngdoc function * @name angularApp.controller:RouteCtrl * @description * # RouteCtrl * Controller of the angularApp */ angular.module('angularApp') .controller('RouteCtrl', function ($scope) { $scope.awesomeThings = [ 'HTML5 Boilerplate', 'AngularJS', 'Karma' ]; });
スペックについては次の通りです:
'use strict'; describe('Controller: RouteCtrl', function () { // load the controller's module beforeEach(module('angularApp')); var RouteCtrl, scope; // Initialize the controller and a mock scope beforeEach(inject(function ($controller, $rootScope) { scope = $rootScope.$new(); RouteCtrl = $controller('RouteCtrl', { $scope: scope }); })); it('should attach a list of awesomeThings to the scope', function () { expect(scope.awesomeThings.length).toBe(3); }); });
テンプレートであるHTMLは次の通りです:
<p>This is the route view.</p>
yo angular:service
$ yo angular:service service create app/scripts/services/service.js create test/spec/services/service.js $
作成されるサービスは次の通りです:
'use strict'; /** * @ngdoc service * @name angularApp.service * @description * # service * Service in the angularApp. */ angular.module('angularApp') .service('service', function () { // AngularJS will instantiate a singleton by calling "new" on this function });
スペックについては次の通りです:
'use strict'; describe('Service: service', function () { // load the service's module beforeEach(module('angularApp')); // instantiate service var service; beforeEach(inject(function (_service_) { service = _service_; })); it('should do something', function () { expect(!!service).toBe(true); }); });
yo angular:provider
$ yo angular:provider provider create app/scripts/services/provider.js create test/spec/services/provider.js $
作成されるプロバイダーは次の通りです:
'use strict'; /** * @ngdoc service * @name angularApp.provider * @description * # provider * Provider in the angularApp. */ angular.module('angularApp') .provider('provider', 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(); }; });
スペックについては次の通りです:
'use strict'; describe('Service: provider', function () { // load the service's module beforeEach(module('angularApp')); // instantiate service var provider; beforeEach(inject(function (_provider_) { provider = _provider_; })); it('should do something', function () { expect(!!provider).toBe(true); }); });
yo angular:factory
$ yo angular:factory factory create app/scripts/services/factory.js create test/spec/services/factory.js $
作成されるファクトリは次の通りです:
'use strict'; /** * @ngdoc service * @name angularApp.factory * @description * # factory * Factory in the angularApp. */ angular.module('angularApp') .factory('factory', function () { // Service logic // ... var meaningOfLife = 42; // Public API here return { someMethod: function () { return meaningOfLife; } }; });
スペックについては次の通りです:
'use strict'; describe('Service: factory', function () { // load the service's module beforeEach(module('angularApp')); // instantiate service var factory; beforeEach(inject(function (_factory_) { factory = _factory_; })); it('should do something', function () { expect(!!factory).toBe(true); }); });
yo angular:value
$ yo angular:value value create app/scripts/services/value.js create test/spec/services/value.js $
作成されるファイルは
'use strict'; /** * @ngdoc service * @name angularApp.value * @description * # value * Value in the angularApp. */ angular.module('angularApp') .value('value', 42);
スペックについては次の通りです:
'use strict'; describe('Service: value', function () { // load the service's module beforeEach(module('angularApp')); // instantiate service var value; beforeEach(inject(function (_value_) { value = _value_; })); it('should do something', function () { expect(!!value).toBe(true); }); });
yo angular:constant
$ yo angular:constant constant create app/scripts/services/constant.js create test/spec/services/constant.js $
作成されるファイルは
'use strict'; /** * @ngdoc service * @name angularApp.constant * @description * # constant * Constant in the angularApp. */ angular.module('angularApp') .constant('constant', 42);
スペックについては次の通りです:
'use strict'; describe('Service: constant', function () { // load the service's module beforeEach(module('angularApp')); // instantiate service var constant; beforeEach(inject(function (_constant_) { constant = _constant_; })); it('should do something', function () { expect(!!constant).toBe(true); }); });
yo angular:decorator
$ yo angular:decorator decorator create app/scripts/decorators/decoratordecorator.js $
作成されるデコレータは次の通りです
'use strict'; /** * @ngdoc function * @name angularApp.decorator:Decorator * @description * # Decorator * Decorator of the angularApp */ angular.module('angularApp') .config(function ($provide) { $provide.decorator('decorator', function ($delegate) { // decorate the $delegate return $delegate; }); });
yo angular:view
HTMLテンプレートを作成します。
$ yo angular:view view create app/views/view.html $
作成されたHTMLは
<p>This is the view view.</p>
最後に
generator-angularのディレクトリは機能毎にディレクトリが定義されています。AngularJSは機能が多いので、こうしたサブジェネレータを利用するとモジュールの書き始めは楽ではないかと思います。