• Stars
    star
    238
  • Rank 168,404 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 10 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Yeoman generator for modular AngularJS apps with Gulp and optional Polymer support

generator-ng-poly

NPM version Build Status Coverage Status All Contributors

Code Climate Dependencies DevDependencies

PRs Welcome Commitizen friendly semantic-release

Yeoman generator for modular AngularJS apps with Gulp and optional Polymer support

Inspired by John Papa's Angular Style Guide and Todd Motto's AngularJS styleguide.

Purpose

This generator focuses on organizing Angular components by feature (home, about, video player, etc.) instead of by type (controller, service, directive, etc.) to encourage the development of self-contained, reusable components.

A typical workflow with this generator consists of creating an Angular module (ng-poly:module) and then generating controllers, directives, etc. for this module to create a new feature.

Polymer is just an added feature, but it isn't required to utilize this generator.

Usage

Install generator-ng-poly:

npm install -g bower gulp yo generator-ng-poly

If TypeScript is going to be used, tsd will need to be installed:

npm install -g tsd

Run yo ng-poly Yeoman will then ask for an app name and language preferences.

If using Node 0.12, there is a bug in Yeoman or Node causing yeoman generators to hang. With ng-poly, if after it outputs the generated home module files it hangs, then it is safe to enter Ctrl+C, etc. The project is good to go and everything else should work normally.

Run gulp to build and start the development environment. More detail on Gulp tasks

User Groups

Please feel free to ask any questions on our GitHub Issues or Google Group.

Generators

Available generators:

Languages and Features supported:

  • Angular Versions
    • 1.2.*, 1.3.*, 1.4.*
  • Markup
    • HAML, HTML, Jade
  • Application scripting languages
    • CoffeeScript, EcmaScript2015 (ES6) with Babel, JavaScript (ES5), TypeScript
  • Testing scripting languages
    • CoffeeScript, EcmaScript2015 (ES6) with Babel, JavaScript (ES5), TypeScriptโ€ 
  • Style languages
    • CSS, LESS, SCSS, Stylus
  • Routers
    • Angular Route, UI Router
  • Unit testing
    • Jasmine (Karma as the test runner) for AngularJS
    • Mocha with Chai (Karma as the test runner) for AngularJS
  • e2e testing
    • Jasmine (ran with Protractor) for AngularJS
    • Mocha, Chai, and Chai as Promised (ran with Protractor) for AngularJS
  • Frameworks (scaffolds simple navbar)
    • Angular Material (1.3.* or higher only)
      • Doesn't scaffold navbar, yet
    • Bootstrap with AngularStrap
    • Bootstrap with UI Bootstrap
    • Foundation with Angular Foundation
  • Polymer
    • Core, Paper
  • Task runners
    • Gulp
  • Other supported Bower packages:
    • Angular Animate
    • Angular Cookies
    • Angular Messages
    • Angular Resource
    • Angular Sanitize
    • Angular Touch
    • Font Awesome
    • Lo-Dash
    • Restangular

Configurations:

โ€  e2e tests are not supported in TypeScript. JavaScript will instead be used for e2e tests.

Gulp Tasks Briefing

gulp will start a localhost and open in the default browser

Using --stage prod will concat and minify HTML, CSS, and Angular modules.

gulp build will compile the assets

gulp dev will call the build task and setup the development environment

gulp unitTest will run unit tests via Karma and create code coverage reports

gulp webdriverUpdate will download the Selenium server standalone and Chrome driver for e2e testing

gulp e2eTest will run e2e tests via Protractor (must start a localhost before running gulp e2eTest)

Gulp Tasks in Detail


All generators ask for a module name except app and element. All generators except app take a name as an argument. A name can be written with CamelCase or hyphens.

Generators requiring a module can take a module option to bypass the prompt:

yo ng-poly:view newView --module=home/kitchen

A module value of app will add the new components to the module defined in app.js or app.coffee.


Examples are shown with HTML, LESS, JavaScript, Jasmine, and UI Router as the app configuration.

App

Asks for application name and language preferences to scaffold out an application with a home module. It will also ask if tests should be placed in the app/ or tests/ directory. It'll ask for some additional Bower dependencies and then install npm and Bower dependencies.

Example:

Run yo ng-poly to get started. ng-poly will then asks you some questions:

[?] What is the app's name?
[?] Which version of Angular should be used?
[?] Which structure should be used?
[?] Which is the preferred markup language?
[?] Which is the preferred application scripting language?
[?] Want to use Controller As syntax?
[?] Should directives be generated using a templateUrl (and markup file) instead of an inline template?
[?] By default, should the route generator create controllers?
[?] Which is the preferred test scripting language?
[?] Which is the preferred unit testing framework?
[?] Which is the preferred e2e testing framework?
[?] Which is the preferred style language?
[?] Should Polymer support be enabled?
[?] Should a framework be setup?
[?] Should ngRoute be used instead of UI Router?
[?] Which additional Bower components should be installed?

ng-poly makes some assumptions, but these can be overridden.

Option Default Value Info
host localhost BrowserSync and Protractor will use this host.
port 3000 BrowserSync and Protractor will use this port.
app-dir app Source code will be generated here.
unit-test-dir app Unit tests will be generated here.
skip-controller false Should the route generator skip creating a controller?
skip-install false Should ng-poly skip installing Bower and npm dependencies?

Example: yo ng-poly --port=8080 --app-dir=src to override the default port and app directory.

A module-only structure produces:

root/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ fonts/ (empty)
โ”‚   โ”œโ”€โ”€ home/
โ”‚   โ”‚   โ”œโ”€โ”€ home-module.{coffee,es6,js,ts}
โ”‚   โ”‚   โ”œโ”€โ”€ home-routes.{coffee,es6,js,ts}
โ”‚   โ”‚   โ”œโ”€โ”€ home.{css,less,scss,styl}
โ”‚   โ”‚   โ”œโ”€โ”€ home.tpl.{haml,html,jade}
โ”‚   โ”‚   โ”œโ”€โ”€ home-controller.{coffee,es6,js,ts}
โ”‚   โ”‚   โ””โ”€โ”€ home-controller_test.{coffee,es6,js,ts}
โ”‚   โ”œโ”€โ”€ images/ (empty)
โ”‚   โ”œโ”€โ”€ app-module.{coffee,es6,js,ts}
โ”‚   โ”œโ”€โ”€ app-routes.{coffee,es6,js,ts}
โ”‚   โ””โ”€โ”€ index.{haml,html,jade}
โ”œโ”€โ”€ bower_components/
โ”œโ”€โ”€ e2e/
โ”‚   โ””โ”€โ”€ home/
โ”‚       โ”œโ”€โ”€ home.po.{coffee,es6,js}
โ”‚       โ””โ”€โ”€ home_test.{coffee,es6,js}
โ”œโ”€โ”€ gulp/
โ”‚   โ”œโ”€โ”€ analyze.js
โ”‚   โ”œโ”€โ”€ build.js
โ”‚   โ”œโ”€โ”€ test.js
โ”‚   โ””โ”€โ”€ watch.js
โ”œโ”€โ”€ node_modules/
โ”œโ”€โ”€ typings/*
โ”œโ”€โ”€ .bowerrc
โ”œโ”€โ”€ .editorconfig
โ”œโ”€โ”€ .eslintrc
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ .jscsrc
โ”œโ”€โ”€ .jshintrc
โ”œโ”€โ”€ .yo-rc.json
โ”œโ”€โ”€ bower.json
โ”œโ”€โ”€ build.config.js
โ”œโ”€โ”€ Gulpfile.js
โ”œโ”€โ”€ karma.config.js
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ protractor.config.js
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ tsd.json*
โ””โ”€โ”€ tslint.json*

A module-type structure produces:

root/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ fonts/ (empty)
โ”‚   โ”œโ”€โ”€ home/
โ”‚   โ”‚   โ”œโ”€โ”€ controllers/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ home-controller.{coffee,es6,js,ts}
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ home-controller_test.{coffee,es6,js,ts}
โ”‚   โ”‚   โ”œโ”€โ”€ views/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ home.{css,less,scss,styl}
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ home.tpl.{haml,html,jade}
โ”‚   โ”‚   โ”œโ”€โ”€ home-module.{coffee,es6,js,ts}
โ”‚   โ”‚   โ””โ”€โ”€ home-routes.{coffee,es6,js,ts}
โ”‚   โ”œโ”€โ”€ images/ (empty)
โ”‚   โ”œโ”€โ”€ app-module.{coffee,es6,js,ts}
โ”‚   โ”œโ”€โ”€ app-routes.{coffee,es6,js,ts}
โ”‚   โ””โ”€โ”€ index.{haml,html,jade}
โ”œโ”€โ”€ bower_components/
โ”œโ”€โ”€ e2e/
โ”‚   โ””โ”€โ”€ home/
โ”‚       โ”œโ”€โ”€ home.po.{coffee,es6,js}
โ”‚       โ””โ”€โ”€ home_test.{coffee,es6,js}
โ”œโ”€โ”€ gulp/
โ”‚   โ”œโ”€โ”€ analyze.js
โ”‚   โ”œโ”€โ”€ build.js
โ”‚   โ”œโ”€โ”€ test.js
โ”‚   โ””โ”€โ”€ watch.js
โ”œโ”€โ”€ node_modules/
โ”œโ”€โ”€ typings/*
โ”œโ”€โ”€ .bowerrc
โ”œโ”€โ”€ .editorconfig
โ”œโ”€โ”€ .eslintrc
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ .jscsrc
โ”œโ”€โ”€ .jshintrc
โ”œโ”€โ”€ .yo-rc.json
โ”œโ”€โ”€ bower.json
โ”œโ”€โ”€ build.config.js
โ”œโ”€โ”€ Gulpfile.js
โ”œโ”€โ”€ karma.config.js
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ protractor.config.js
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ tsd.json*
โ””โ”€โ”€ tslint.json*

* Only TypeScript projects will have this.

Constant

Generates a constant and its test.

Example:

yo ng-poly:constant theHero
[?] Which module is this for?

Produces app/module/the-hero-constant.js:

(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name module.constant:theHero
   *
   * @description
   *
   */
  angular
    .module('module')
    .constant('theHero', 0);
}());

Produces app/module/the-hero-constant_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('theHero', function () {
  var constant;

  beforeEach(module('module'));

  beforeEach(inject(function (theHero) {
    constant = theHero;
  }));

  it('should equal 0', function () {
    expect(constant).toBe(0);
  });
});

Controller

Genrates a controller and its test.

Example:

yo ng-poly:controller micro
[?] Which module is this for?

Produces app/module/micro-controller.js:

(function () {
  'use strict';

  /**
   * @ngdoc object
   * @name module.controller:MicroCtrl
   * @requires $scope
   *
   * @description
   *
   */
  angular
    .module('module')
    .controller('MicroCtrl', MicroCtrl);

  function MicroCtrl($scope) {
    $scope.micro = {};
    $scope.micro.ctrlName = 'MicroCtrl';
  }
}());

Produces app/module/micro-controller_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('MicroCtrl', function () {
  var scope;

  beforeEach(module('module'));

  beforeEach(inject(function ($rootScope, $controller) {
    scope = $rootScope.$new();
    $controller('MicroCtrl', {$scope: scope});
  }));

  it('should have ctrlName as MicroCtrl', function () {
    expect(scope.micro.ctrlName).toEqual('MicroCtrl');
  });
});

Decorator

Generates a decorator and its test.

Example:

yo ng-poly:decorator awesomeService
[?] Which module is this for?

Note: If decorating a service starting with a $ you must escape it like:

yo ng-poly:decorator \$state

Produces app/module/awesome-service-decorator.js:

(function () {
  'use strict';

  /**
   * @ngdoc decorator
   * @name home.decorator:awesomeService
   * @restrict EA
   * @element
   *
   * @description
   *
   */
  angular
    .module('module')
    .config(decorator);

  function decorator($provide) {
    $provide.decorator('awesomeService', function ($delegate) {
      $delegate.simpleFunction = function () {
        return 'awesomeService';
      };
      return $delegate;
    });
  }
}());

Produces: app/module/awesome-service-decorator_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('awesomeService', function () {
  var decorator;

  beforeEach(module('module'));

  beforeEach(inject(function (awesomeService) {
    decorator = awesomeService;
  }));

  it('should have simpleFunction return awesomeService', function () {
    expect(decorator.simpleFunction()).toEqual('awesomeService');
  });
});

Directive

Generates a directive, its template, and its test.

Example:

yo ng-poly:directive fancy-button
[?] Which module is this for?

Produces app/module/fancy-button-directive.js:

(function () {
  'use strict';

  /**
   * @ngdoc directive
   * @name module.directive:fancyButton
   * @restrict EA
   * @element
   *
   * @description
   *
   * @example
     <example module="module">
       <file name="index.html">
        <fancy-button></fancy-button>
       </file>
     </example>
   *
   */
  angular
    .module('module')
    .directive('fancyButton', fancyButton);

  function fancyButton() {
    return {
      restrict: 'EA',
      scope: {},
      templateUrl: 'module/fancy-button-directive.tpl.html',
      replace: false,
      controller: function (scope) {
        scope.fancyButton = {};
        scope.fancyButton.name = 'fancyButton';
      },
      link: function (scope, element, attrs) {
        /*jshint unused:false */
        /*eslint "no-unused-vars": [2, {"args": "none"}]*/
      }
    };
  }
}());

Produces app/module/fancy-button-directive.tpl.html:

<div>{{fancyButton.name}}</div>

Produces app/module/fancy-button-directive_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('fancyButton', function () {
  var scope;
  var element;

  beforeEach(module('module', 'module/fancy-button-directive.tpl.html'));

  beforeEach(inject(function ($compile, $rootScope) {
    scope = $rootScope.$new();
    element = $compile(angular.element('<fancy-button></fancy-button>'))(scope);
  }));

  it('should have correct text', function () {
    scope.$apply();
    expect(element.isolateScope().fancyButton.name).toEqual('fancyButton');
  });
});

The directive's template (HAML, HTML, or Jade) is converted to a temporary module automatically for testing.

Factory

Generates a factory and its test.

Example:

yo ng-poly:factory cake
[?] Which module is this for?

Produces app/module/cake-factory.js:

(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name module.factory:Cake
   *
   * @description
   *
   */
  angular
    .module('module')
    .factory('Cake', Cake);

  function Cake() {
    var CakeBase = {};
    CakeBase.someValue = 'Cake';
    CakeBase.someMethod = function () {
      return 'Cake';
    };
    return CakeBase;
  }
}());

Produces app/module/Cake-factory_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('Cake', function () {
  var factory;

  beforeEach(module('module'));

  beforeEach(inject(function (Cake) {
    factory = Cake;
  }));

  it('should have someValue be Cake', function () {
    expect(factory.someValue).toEqual('Cake');
  });

  it('should have someMethod return Cake', function () {
    expect(factory.someMethod()).toEqual('Cake');
  });
});

Filter

Generates a filter and its test.

Example:

yo ng-poly:filter coffee
[?] Which module is this for?

Produces app/module/coffee-filter.js:

(function () {
  'use strict';

  /**
   * @ngdoc filter
   * @name module.filter:coffee
   *
   * @description
   *
   * @param {Array} input The array to filter
   * @returns {Array} The filtered array
   *
   */
  angular
    .module('module')
    .filter('coffee', coffee);

  function coffee() {
    return function (input) {
      var temp = [];
      angular.forEach(input, function (item) {
        if(item > 3) {
          temp.push(item);
        }
      });
      return temp;
    };
  }
}());

Produces app/module/coffee-filter_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('coffee', function () {
  beforeEach(module('module'));

  it('should filter our numbers not greater than 3', inject(function ($filter) {
    expect($filter('coffee')([1,2,3,4])).toEqual([4]);
  }));
});

Module

Generates a new module and create a new route. Updates parent module's dependencies.

Top Level Example:

yo ng-poly:module top

Produces app/top/top-module.js:

(function () {
  'use strict';

  /* @ngdoc object
   * @name top
   * @description
   *
   */
  angular
    .module('top', [
      'ui.router'
    ]);
}());

Produces pp/top/top-routes.js:

(function () {
  'use strict';

  angular
    .module('top')
    .config(config);

  function config($stateProvider) {
    $stateProvider
      .state('top', {
        url: '/top',
        templateUrl: 'top/top.tpl.html',
        controller: 'TopCtrl'
      });
  }
}());

Produces app/top/top-controller.js, app/top/top-controller_test.js, app/top/top.tpl.html, app/top/top.less, e2e/top/top.po.js, e2e/top/top_test.js

Updates app/app-module.js:

(function () {
  'use strict';

  /* @ngdoc object
   * @name module
   * @requires $urlRouterProvider
   * @description
   *
   */
  angular
    .module('module', [
      'ui.router',
      'home',
      'top'
    ]);
}());

Deep Level Example:

yo ng-poly:module top/bottom

Produces app/top/bottom/bottom-module.js, app/top/boottom/bottom-routes.js, app/top/bottom/bottom-controller.js, app/top/bottom/bottom-controller_test.js, app/top/bottom/bottom.tpl.html, app/top/bottom/bottom.less, e2e/bottom/bottom.po.js, e2e/bottom/bottom_test.js

Updates app/top/top-module.js:

(function () {
  'use strict';

  /* @ngdoc object
   * @name top
   * @requires $stateProvider
   *
   * @description
   *
   */
  angular
    .module('top', [
      'ui.router',
      'top.bottom'
    ]);
}());

Notice the module in app/top/bottom/ is called 'top.bottom'. All tests in this directory use this nomenclature, as well.


Deeper Level Example:

yo ng-poly:module top/bottom/bottomest

Produces 'bottom.bottomest' module and routes, a controller, controller test, style, and a view in app/top/bottom/bottomest/

Updates 'top.bottom' module with the new 'bottom.bottemest' module as a dependency.


Deeperestier Level Example:

It just keeps going...


Empty modules

By running ng-poly:module newHome --empty a module's routes file will not be created.

The module file will omit the router dependency:

(function () {
  'use strict';

  /* @ngdoc object
   * @name newHome
   *
   * @description
   *
   */
  angular
    .module('newHome', [
    ]);
}());

Provider

Generates a provider and its test.

Example:

yo ng-poly:provider bacon
[?] Which module is this for?

Produces app/module/bacon-provider.js:

(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name module.provider:Bacon
   *
   * @description
   *
   */
  angular
    .module('module')
    .provider('Bacon', Bacon);

  function Bacon() {
    return {
      $get: function () {
        return 'Bacon';
      }
    };
  }
}());

Produces app/module/Bacon-provider_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('Bacon', function () {
  var provider;

  beforeEach(module('module'));

  beforeEach(inject(function (Bacon) {
    provider = Bacon;
  }));

  it('should equal Bacon', function () {
    expect(provider).toEqual('Bacon');
  });
});

Route

Adds a new route and generates a controller and view. The name provided is used as state name for UI Router and as the route URL for ngRoute. Yeoman will then ask for the module to add the route to, the URL for the route (UI Router only), and the templateUrl. It will also generate an e2e test and a Page Object model for the new route.

Example:

yo ng-poly:route your-place
[?] Which module is this for?
[?] What's the URL for this route? (UI Router only)
[?] What's the templateURL for this route?

Updates app/module/module-module.js:

(function () {
  'use strict';

  /* @ngdoc object
   * @name module
   * @requires $stateProvider
   *
   * @description
   *
   */
  angular
    .module('module', [
      'ui.router'
    ]);

  angular
    .module('module')
    .config(config);

  function config($stateProvider) {
    $stateProvider
      .state('module', {
        url: '/module',
        templateUrl: 'module/module.tpl.html',
        controller: 'ModuleCtrl'
      })
      .state('yourPlace', {
        url: '/yourPlace',
        templateUrl: 'module/your-place.tpl.html',
        controller: 'YourPlaceCtrl'
      });
  }
}());

Produces e2e/your-place/your-place.po.js:

/*global element, by*/
'use strict';

var YourPlacePage = function () {
  this.text = element(by.tagName('p'));
  this.heading = element(by.tagName('h2'));
};

module.exports = YourPlacePage;

Produces e2e/your-place/your-place_test.js:

/*global describe, beforeEach, it, browser, expect */
'use strict';

var buildConfigFile = require('findup-sync')('build.config.js')
  , buildConfig = require(buildConfigFile)
  , YourPlacePagePo = require('./your-place.po');

describe('Your place page', function () {
  var yourPlacePage;

  beforeEach(function () {
    yourPlacePage = new YourPlacePagePo();
    browser.driver.get(buildConfig.host + ':' + buildConfig.port + '/#/yourPlace');
  });

  it('should say YourPlaceCtrl', function () {
    expect(yourPlacePage.heading.getText()).toEqual('yourPlace');
    expect(yourPlacePage.text.getText()).toEqual('YourPlaceCtrl');
  });
});

Produces app/module/your-place-controller.js, app/module/your-place-controller_test.js, app/module/your-place.tpl.html, and app/module/your-place.less

Currently, the module must have an existing state for another to be added.


The route generator can take URL and templateUrl options, as well.

yo ng-poly:route yourPlace --url=yourPlace --template-url=your-place

The URL will automatically be prepended with / and and the templateUrl will be appended with .tpl.html.


Service

Generates a service and its test.

Example:

yo ng-poly:service cheap-or-good
[?] Which module is this for?

Produces app/module/cheap-or-good-service.js:

(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name home.service:CheapOrGood
   *
   * @description
   *
   */
  angular
    .module('module')
    .service('CheapOrGood', CheapOrGood);

  function CheapOrGood() {
    var self = this;

    self.get = function get() {
      return 'CheapOrGood';
    };
  }
}());

Produces app/module/cheap-or-good-service_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('CheapOrGood', function () {
  var service;

  beforeEach(module('module'));

  beforeEach(inject(function (CheapOrGood) {
    service = CheapOrGood;
  }));

  it('should equal CheapOrGood', function () {
    expect(service.get()).toEqual('CheapOrGood');
  });
});

Value

Generates a value and its test.

Example:

yo ng-poly:value morals
[?] Which module is this for?

Produces app/module/morals-value.js:

(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name module.constant:morals
   *
   * @description
   *
   */
  angular
    .module('module')
    .value('morals', 0);
}());

Produces app/module/morals-value_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('morals', function () {
  var value;

  beforeEach(module('module'));

  beforeEach(inject(function (morals) {
    value = morals;
  }));

  it('should equal 0', function () {
    expect(value).toBe(0);
  });
});

View

Generates a view and its style.

Example:

yo ng-poly:view nice
[?] Which module is this for?

Produces app/module/nice-view.tpl.html:

<h2>nice</h2>
<p>{{nice.ctrlName}}</p>

Produces an empty file app/module/nice-view.less


Element

Generates a Polymer element.

Example:

yo ng-poly:element gold-silver

Produces app/components/gold-silver/gold-silver.less:

:host {
  height: 100px;
  width: 100px;
  display: inline-block;
}

Produces app/components/gold-silver/gold-silver.html:

<link rel='import' href='../polymer/polymer.html'>

<polymer-element name='gold-silver'>
  <template>
    <link rel='stylesheet' href='gold-silver.css'>
    <div>{{name}}</div>
  </template>

  <script src='gold-silver.js'></script>
</polymer-element>

Produces app/components/gold-silver/gold-silver.js:

/*global Polymer*/
(function () {
  'use strict';

  var element = new Polymer({
    is: 'gold-silver',
    ready: function () {
      console.log('gold-silver');
    }
  });

  return element;
}());

Configurations

It is possible to override some configurations initially specified when yo ng-poly was ran.

Each generator is able to take the following arguments. For example, yo ng-poly:module test --skip-controller=true will override the configuration settings for everything generated by this command.

Option Possible Values Description
directive-template-url true, false Use external markup files and templateUrl instead of template in directives
skip-controller true, false Skip creating controllers when generating routes and modules

It's not recommended to mix ngRoute and UI Router, but it's possible.

Controller As Syntax

This generator has support for the Controller As syntax. Yeoman will ask if this should be enabled when ng-poly:app is ran.

This will generate controllers like:

(function () {
  'use strict';

  /**
   * @ngdoc object
   * @name home.controller:HomeCtrl
   *
   * @description
   *
   */
  angular
    .module('home')
    .controller('HomeCtrl', HomeCtrl);

  function () {
    var vm = this;
    vm.ctrlName = 'HomeCtrl';
  }
}());

...and their tests like:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('HomeCtrl', function () {
  var ctrl;

  beforeEach(module('home'));

  beforeEach(inject(function ($rootScope, $controller) {
    ctrl = $controller('HomeCtrl');
  }));

  it('should have ctrlName as HomeCtrl', function () {
    expect(ctrl.ctrlName).toEqual('HomeCtrl');
  });
});

It'll also modify the state's controller like:

(function () {
  'use strict';

  /* @ngdoc object
   * @name home
   * @requires $stateProvider
   *
   * @description
   *
   */
  angular
    .module('home', [
      'ui.router'
    ]);

  angular
    .module('home')
    .config(config);

  function config($stateProvider) {
    $stateProvider
      .state('home', {
        url: '/home',
        templateUrl: 'home/home.tpl.html',
        controller: 'HomeCtrl as home'
      });
  }
}());

Directives will be generated like:

(function () {
  'use strict';

  /**
   * @ngdoc directive
   * @name home.directive:fancyButton
   * @restrict EA
   * @element
   *
   * @description
   *
   * @example
     <example module="home">
       <file name="index.html">
        <fancy-button></fancy-button>
       </file>
     </example>
   *
   */
  angular
    .module('home')
    .directive('fancyButton', fancyButton);

  function fancyButton() {
    return {
      restrict: 'EA',
      scope: {},
      templateUrl: 'home/fancy-button-directive.tpl.html',
      replace: false,
      controllerAs: 'fancyButton',
      controller: function () {
        var vm = this;
        vm.name = 'fancyButton';
      },
      link: function (scope, element, attrs) {
        /*jshint unused:false */
        /*eslint "no-unused-vars": [2, {"args": "none"}]*/
      }
    };
  }
}());

Lastly, views will be generated like:

<h2>home</h2>
<p>{{home.ctrlName}}</p>

Directive TemplateUrl

This generator has supporting for creating directives with inline templates and external markup files using templateUrl.

If Directive TemplateUrl is enabled, directives will be created as described above.

If Directive TemplateUrl is disabled, directives will be created like below.

Example:

yo ng-poly:directive fancy-button
[?] Which module is this for?

Produces app/module/fancy-button-directive.js:

(function () {
  'use strict';

  /**
   * @ngdoc directive
   * @name module.directive:fancyButton
   * @restrict EA
   * @element
   *
   * @description
   *
   * @example
     <example module="module">
       <file name="index.html">
        <fancy-button></fancy-button>
       </file>
     </example>
   *
   */
  angular
    .module('module')
    .directive('fancyButton', fancyButton);

  function fancyButton() {
    return {
      restrict: 'EA',
      scope: {},
      template: '<div>{{fancyButton.name}}</div>',
      replace: false,
      controller: function (scope) {
        scope.fancyButton = {};
        scope.fancyButton.name = 'fancyButton';
      },
      link: function (scope, element, attrs) {
        /*jshint unused:false */
        /*eslint "no-unused-vars": [2, {"args": "none"}]*/
      }
    };
  }
}());

Produces app/module/fancy-button-directive_test.js:

/*global describe, beforeEach, it, expect, inject, module*/
'use strict';

describe('fancyButton', function () {
  var scope;
  var element;

  beforeEach(module('module'));

  beforeEach(inject(function ($compile, $rootScope) {
    scope = $rootScope.$new();
    element = $compile(angular.element('<fancy-button></fancy-button>'))(scope);
  }));

  it('should have correct text', function () {
    scope.$apply();
    expect(element.isolateScope().fancyButton.name).toEqual('fancyButton');
  });
});

Gulp Tasks in Detail

Items in italics are only ran in --stage=prod

Available tasks:

  • gulp or gulp default
  • Runs gulp dev
  • gulp dev
  • Runs gulp build and starts BrowserSync and Gulp's watch
  • gulp build
  • Runs gulp analyze
  • Runs gulp clean to delete build directory
  • Runs gulp markup to compile Haml and Jade to HTML
  • Runs gulp styles to compile Less, SCSS, and Stylus (with Nib), add vendor prefixes, modify images and font URLs, concat, minify, and rev
  • Runs gulp scripts to compile ES2015, CoffeeScript, and TypeScript, injects HTML templates in $templateCache, sorts Angular files, annotates, minifies, and rev
  • Runs gulp inject to inject sorted JS and CSS source files into build/index.html
  • Runs gulp bowerCopy to modify image and font URLs in vendor CSS files, concat vendor CSS, minify vendor CSS, rev vendor CSS, copy vendor CSS to build, concat vendor JS, minify vendor JS and leave licenses intact, copy vendor JS to build
  • Runs gulp bowerInject to inject vendor CSS and JS into build/index.html
  • Runs gulp bowerAssets to copy over any vendor image and fonts to build/
  • Runs gulp fonts to copy app fonts to build/
  • Runs gulp images to copy app images to build/
  • Runs gulp copyTemplates to copy compiled templates to a separate test directory used for unit testing
  • Runs gulp deleteTemplates to delete templates in build
  • gulp unitTest
  • Runs gulp lint
  • Runs gulp clean:test to delete previous compiled unit tests
  • Runs gulp buildTests to compile CoffeeScript, ES2015, and TypeScript unit tests
  • Runs gulp build
  • Runs gulp karmaFiles to automatically configure Bower dependencies, directive templates, sorted build JS files, and unit tests for Karma
  • Run unit tests with Karma
  • gulp e2eTest
  • Runs gulp lint
  • Runs gulp build
  • Runs gulp build:e2eTest to compile CoffeeScript, ES2015, and TypeScript tests
  • Runs Protractor to perform e2eTest (app needs to be running via gulp default)
  • gulp webdriverUpdate downloads Selenium and webdrivers for e2e testing
  • gulp analyze
  • Analyzes source and test code with CoffeeLint, TSLint, ESLint, JSHint, and JSCS
  • Uses Plato to inspect source and test for complexity and maintainability

How to Add Polymer elements

Currently, this process isn't as simple as desired. Pull requests are greatly appreciated to help this process in any way.

For this, we're going to install and setup paper-toolbar.

  1. Run bower install --save polymerelements/paper-toolbar to download paper-toolbar and its dependencies.
  2. Digging through bower_components/paper-toolbar/, we can determine it needs to have paper-toolbar/paper-toolbar.html, paper-styles/paper-styles.html, and polymer/polymer. We then dig through bower_components/paper-styles/ to find it needs paper-styles/paper-styles.html, paper-styles/color.html, paper-styles/default-theme.html, paper-styles/shadow.html, paper-styles/typography.html, iron-flex-layout/iron-flex-layout.html, and iron-flex-layout/classes/iron-flex-layout.html. Then we dig through iron-flex-layout/iron-flex-layout to find out we just need to additionally include iron-flex-layout/iron-flex-layout/classes/iron-shadow-flex-layout.html.
  3. Edit the components task in gulp/build.js to include polymerBowerAssetsToCopy like:
polymerBowerAssetsToCopy = [
  'polymer/polymer*.html',
  'iron-flex-layout/iron-flex-layout.html',
  'iron-flex-layout/classes/*.html',
  'paper-styles/{color,default-theme,paper-styles,shadow.html,typography.html}',
  'paper-toolbar/paper-toolbar.html'
].map(function (file) {
  return bowerDir + file;
});
  1. Edit the componentsInject task in gulp/build.js to include
var polymerAssetsToInject = [
  'polymer/polymer.html',
  'paper-styles/paper-styles.html'
].map(function (file) {
  return config.buildComponents + file;
});
  1. Now, we can use the <paper-toolbar> element in our code.

Note: for custom components, we just need to include them in polymerAssetsToInject. They are all automically copied.


Contributors

Thanks goes to these wonderful people (emoji key):


Dustin Specker

๐Ÿ’ป ๐Ÿ“– โš ๏ธ

Binh Nguyen

๐Ÿ’ป ๐Ÿ“– โš ๏ธ

Roman C. Podolski

๐Ÿ’ป

David Brown

๐Ÿ’ป ๐Ÿ“–

David Steinkopff

๐Ÿ’ป

Frode Egeland

๐Ÿ’ป โš ๏ธ

Scott Busche

๐Ÿ’ป

Rafael Zeffa

๐Ÿ’ป โš ๏ธ

PatrickJS

๐Ÿ“–

Tiago de Assis Gonรงalves

๐Ÿ’ป

Ruslan Stelmachenko

๐Ÿ’ป

Jeff Arese Vilar

๐Ÿ’ป

This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT

More Repositories

1

awesome-eslint

A list of awesome ESLint plugins, configs, etc.
4,289
star
2

awesome-flow

A list of awesome Flow integrations, tools, tutorials, etc.
123
star
3

eslint-plugin-no-use-extend-native

ESLint plugin to prevent use of extended native objects
JavaScript
55
star
4

dscript

Framework agnostic hyperscript
JavaScript
35
star
5

eslint-config-angular

ESLint shareable config for Angular plugin
JavaScript
24
star
6

gulp-modify-css-urls

Gulp plugin for modifying CSS URLs
JavaScript
19
star
7

pushit

Guarantee Git pushes real good with Salt-N-Pepa
JavaScript
17
star
8

gulp-alex

Gulp plugin for Alex
JavaScript
7
star
9

redux-immutable-combine-reducers

A Redux combineReducers that returns an Immutable Map
JavaScript
7
star
10

convert-vinyl-to-vfile

Convert a Vinyl file to a VFile
JavaScript
6
star
11

deku-redux-connect

Like react-redux's connect, but for Deku 2.0.0
JavaScript
6
star
12

go-singly-linked-list

A Singly Linked List in Go
Go
6
star
13

ansible-dotfiles

I DevOps'd my dotfiles
Jinja
5
star
14

kpt-remove-resource

a kpt function for removing a Kubernetes resource
Go
5
star
15

eslint-config-dustinspecker

ESLint shareable config of Dustin Specker's preferences
JavaScript
4
star
16

convert-css-color-name-to-hex

Convert CSS color names to hex
JavaScript
4
star
17

argo-prometheus-example

Shell
3
star
18

shorten-css-hex

Shorten CSS hex codes
JavaScript
3
star
19

dscript-react

dscript with React setup done for you
JavaScript
3
star
20

random-wiki

Get a random topic from Wikipedia.org
JavaScript
3
star
21

is-fibonacci-number

Elm
3
star
22

conjunction

Combine a list of strings with a conjunction
Elixir
3
star
23

pulumi-libvirt-ubuntu-example

Go
3
star
24

eslint-generate-config-from-sample

Create an ESLint config for existing code
JavaScript
3
star
25

go-combined-unit-integration-coverage-demo

Go
3
star
26

string-replace-with-object

JavaScript
3
star
27

cks-vagrant

Vagrantfile to create cluster for use with Kubernetes CKS 2020 Complete Course + Simulator
Shell
3
star
28

lockal

a user/project local executable dependency manager
Go
3
star
29

is-css-color-name

Determine if a name is a valid CSS color name
JavaScript
2
star
30

deku-prop-types

Prop type validation for Deku components
JavaScript
2
star
31

dscript-deku

dscript with Deku setup done for you
JavaScript
2
star
32

kpt-demo

to go along with: https://dustinspecker.com/posts/introduction-to-kpt/
2
star
33

carvel-suite-example

Shell
2
star
34

paperback

Easily generate files from templates
JavaScript
2
star
35

array-join-conjunction

Join an array with a conjunction
JavaScript
2
star
36

list-join-conjunction

Join a List with a conjunction
Elm
2
star
37

dict-key-values

Swap the key value pairs of a Dict
Elm
2
star
38

parse-css-class-id-selector

Retreive class names and id from a CSS selector
JavaScript
2
star
39

newline-regex

Regex for newline characters
JavaScript
2
star
40

deku-prop-types-immutable

Immutable prop type validation for Deku components
JavaScript
2
star
41

austin

Add the *Powers* of spying to JavaScript tests
JavaScript
2
star
42

pulumi-libvirt-ubuntu-component-resources-example

Go
2
star
43

generator-ds-mod

Yeoman Generator for creating Node modules
JavaScript
1
star
44

checker-factory

JavaScript
1
star
45

tampermonkey-scripts

JavaScript
1
star
46

const-func

Create a function always returning a constant
JavaScript
1
star
47

is-obj-prop

Does a JS type have a property
JavaScript
1
star
48

func-has-param

Check if function in file has parameter
JavaScript
1
star
49

is-get-set-prop

Does a JS type have a getter/setter property
JavaScript
1
star
50

last

Elm
1
star
51

paperback-example

An example of how to use paperback
JavaScript
1
star
52

string-surround

Surround a string with another string
JavaScript
1
star
53

gite

An Electron app alternative to gitk
JavaScript
1
star
54

capitalize-word

Elm
1
star
55

os

Assembly
1
star
56

string-contains-string

Check if one of two strings contains the other
JavaScript
1
star
57

dustinspecker.com

HTML
1
star
58

obj-props

List of properties for JavaScript objects
JavaScript
1
star
59

is-proto-prop

Does a JS type's prototype have a property
JavaScript
1
star
60

dscript-mapper

Map models between stateless function components from different frameworks
JavaScript
1
star
61

prepend-if

Prepend a string, conditionally
JavaScript
1
star
62

gomega-lint

Go
1
star
63

get-lodash-template-vars

Retrieve list of vars in a lodash template
JavaScript
1
star
64

happy-news

Create happier comments on Hacker News https://chrome.google.com/webstore/detail/happy-news/ndldkhjhhnkgnnbbgdmpoaopnikopbjj
JavaScript
1
star
65

dscript-doc

dscript with doc-jsx setup done for you
JavaScript
1
star
66

vim-snippets-dustinspecker

Dustin Specker's snippets
1
star
67

learn-python-the-hard-way

Exercises from Learn Python the Hard Way
Python
1
star
68

dotfiles

Vim Script
1
star
69

gulp-ng-new-router-templates

Gulp plugin for injecting template paths into $componentLoaderProvider
JavaScript
1
star
70

git-gerrit

Git commands Dustin uses with Gerrit
Shell
1
star
71

us-states

Elm
1
star
72

doc-jsx

A JSX pragma for document
JavaScript
1
star
73

exercism

Elixir
1
star
74

get-yo-rc-path

Get the path of the nearest .yo-rc.json file
JavaScript
1
star
75

hapi-ts-experiment

Experimenting using TypeScript with Hapi
TypeScript
1
star
76

count-spaces

Count number of spaces
JavaScript
1
star
77

voting-server

Learning React, Redux, and Immutable http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html
JavaScript
1
star
78

go-by-example

Go By Example tutorial
Go
1
star
79

fizzbuzz-example

Trying out Sinon's spying on console.log.
JavaScript
1
star
80

advent-of-code-2017

JavaScript
1
star
81

is-css-color-hex

Determine if a string is a valid CSS color hex
JavaScript
1
star
82

network-namespaces-example

A script to automate what https://dustinspecker.com/posts/how-do-kubernetes-and-docker-create-ip-addresses/ creates.
Shell
1
star
83

append-if

Append a string, conditionally
JavaScript
1
star
84

discord-notify-ip-change

Go
1
star
85

go-lint-rule-demo

Go
1
star