This project is an application skeleton for an AngularJS web application. It is based on the experience we have building our first enterprise scale angular application at Kunstmaan. With this you can quickly bootstrap your angular application and dev environment. This seed contains a small sample AngularJS application which shows you how we like…
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app
grunt
test
.bowerrc
.editorconfig
.gitignore
.jshintignore
.jshintrc
Gruntfile.js
LICENSE
README.md
bower.json
package.json

README.md

Angular Super-Seed for enterprise scale AngularJS applications

This project is an application skeleton for an AngularJS web application. It is based on the experience we have building our first enterprise scale angular application at Kunstmaan. With this you can quickly bootstrap your angular application and dev environment.

This seed contains a small sample AngularJS application which shows you how we like to structure our code and how the code should interact.

Included Features:

Getting Started

To get started you can simply clone this repository and install the necessary dependencies:

Clone angular-super-seed

Clone the angular-seed repository using git:

git clone https://github.com/Kunstmaan/angular-super-seed
cd angular-super-seed

Install Dependencies

There are two kinds of dependencies you need for this project:

  • tools which helps us manage and test the application, these dependencies can be managed using node package manager.
npm install
  • AngularJS and other 3rd party libraries are managed via bower.
bower install

npm install will also trigger bower install after npm is finished installing.

When the dependencies are successfully installed you should find two extra folders in your project.

  • ./node_modules - contains the npm packages for the tools we need
  • ./app/bower_vendor - contains the 3rd party libraries

Run the Application

We have configured a simple development web server in this project based on grunt-contrib-connect. This is automatically started on port 9000 when running grunt.

To easily start this web server with the standard development environment:

grunt

It will automatically open your browser and navigate to the right url.

Directory Layout

app/
|- index.html            --> the main template file.
|- .htaccess             --> apache2 configuration file.
|- scss/                 --> scss files.
|- img/                  --> image files.
|- fonts/                --> font files.
|- config/               --> environment specific configuration.
|  |- config.json        --> global configuration used across all environments.
|  |- config_dev.json    --> configuration specific for development environment.
|  |                         will override keys in default config.
|  |- config_prod.json   --> configuration specific for production environment.
|  |- config_test.json   --> configuration specific for test environment used in e2e.
|- js/                   --> javascript files.
|  |- app.js             --> define app modules + dependencies.
|  |- <my_feature>       --> a custom feature folder.
|  |  |- config/         --> the configuration for this feature.
|  |  |  |- config.json  --> the configuration specific for this feature.
|  |  |  └- states.json  --> the configured states for this feature.
|  |  |- views/          --> the views for this feature.
|  |  |                      when looking for a template in a feature it'll look here.
|  |  |- controllers/    --> the controllers for this feature.
|  |  |- directives/     --> the directives for this feature.
|  |  |- services/       --> the services for this feature.
|  |  |- <my_feature>.js --> file containing config / run phases for your feature module (if any).
|  |  └- */              --> whatever you want! (filters, translations, ...)
|  └- common/*           --> feature folder to store common code.
|                            already contains utility services needed for the seed to work.
|                            common/config/config.js will be automatically generated by grunt config. 
|                            don't modify config.js as it'll be overwritten.
grunt/                   --> we've split out grunt config in multiple files for maintainability.
|- middleware/           --> convenient place to store middleware loaded by grunt-contrib-connect.
|- plugins/              --> some custom grunt tasks we created.
|- common.js             --> grunt config for cleaning up builds.
|- frontend.js           --> grunt config for scss, svg2png, imagemin, modernizr and watches for scss changes.
|- javascript.js         --> grunt config related to build and linting + watches for javascript changes.
|- server.js             --> grunt-contrib-connect + livereload config.
|- testing.js            --> grunt config for karma, protractor + triggering tests on filechange.
└- templates.js          --> grunt config related to creating template cache for testing and build.
test/
|- helpers/              --> contains helper functions for the unit tests. check 'Testing' part.
|- unit/                 --> contains unit tests. check 'Testing' part.
└- e2e/                  --> contains end2end tests. check 'Testing' part.
Gruntfile.js             --> grunt configuration. actual grunt task definitions.
package.json             --> npm configuration (tools).
bower.json               --> bower configuration (3rd party libraries).

Grunt tasks

General

grunt: spins up a development server and opens up the right url in your default browser.

  • Watches all your files and executes live reload when necessary.
  • Executes unit tests in phantomjs runner after altering javascript files (brew install phantomjs on OS X).
  • Executes jshint after altering javascript files and blocks running unit tests.

important: Unit tests won't run when there are jshint errors. This is because we believe your tests will often fail when jshint detects an error. Your code has to be correct before the tests are run. grunt test:default will run your unit tests no matter the jshint status.

Files are served using grunt-contrib-connect. This allows you to inject custom middlewares which can be very useful. You could for example reverse-proxy your API endpoint as if it were on your local development machine. This allows you to work around CORS (Cross Origin Resource Sharing) issues in browsers that don't follow CORS policy headers like IE8.

grunt build: builds the app ready for deploy in the ./dist directory.

  • Minifies and concatenates the javascript and css files.
  • Creates a template cache.
  • Generates the config app, you can specify the environment using APP_ENV={env} for example: APP_ENV=prod grunt build will build the application using the production configuration.
  • Prefers minified dependencies if they are stored next to the original dependencies. Will take jquery-2.0.min.js over jquery-2.0.js.
  • File revisioning.

Testing

Testing is important in any application. The seed comes packed with karma and protractor pre-configured with sane defaults. We include things like mocha with chai and sinon. We chose mocha because it's more flexible than Jasmine and we were able to choose our own assertion libraries, etc. Chai is a better matcher library that allows you to write cleaner expectations. Sinon allows you to mock, stub and spy to your hearts content.

grunt test:default: runs all your unit tests using karma in a single run in a chrome browser.

npm test is an alias for this.

  • Configuration for unit tests can be found under ./test/karma-unit.conf.js.
  • Unit tests themselves are created under ./test/unit/<feature>/**/* and follow the same structure as your feature folders. If your original file is located under controllers it should be located under the same controllers folder in the test feature folder.

The unit tests all some contain handy helper functions in the ./test/helpers folder. When testing directives using app.helpers.loadLocalTemplatesCache() makes sense to invoke since it'll load in your entire template cache allowing you to test the directives with the actual templates. You won't have to mock the $templateCache.

It also contains some functions to invoke keypresses and throw events which sometimes go wrong with browserTrigger (which is also included in the ./test/lib/ folder).

Even if jshint fails the tests will still run with grunt test:default.

grunt test:ci: runs all your unit tests using karma in a single run in phantomjs and chrome.

  • This will generate cobertura coverage reports. You can ignore files in your coverage by placing ci:coverage:exclude somewhere in your file. Preferably in a comment section.
  • This will generate a junit report.

grunt test:e2e: runs your end 2 end / integration tests using protractor.

Protractor simulates interaction with our web app and verifies that the application responds correctly. Therefore, our web server needs to be serving up the application, so that protractor can interact with it.

It's configured to use the Cucumber/Gherkin syntax. A sample is included in ./test/e2e along with some useful steps. I am on state "state_name" is especially useful because it allows you to move around your app using the states.

You can optionally add a regular expression it needs to check for in order for the state to be accepted. A use-case for this is where your state has a variable in the url. I am on state "news.details" (/news/(\d*)).

To start the tests you first need a selenium server. Run npm run update-webdriver to install or update your WebDriver.

If you have the latest webdriver, run npm run protractor to spin up an instance of protractor. You'll need to have this running in the background.

When a protractor instance is running you can execute the tests using the grunt test:e2e command.

  • The configuration is found at ./test/e2e.conf.js.
  • The tests are located in ./test/e2e/<feature>/*.
  • Default steps are provided in common which hook into the route configuration.

Running the App in Production

This seed can create a 'build' using APP_ENV=prod grunt build which drops a generated application in the ./dist folder. These are versioned static files which can be hosted anywhere.

You'll need to configure a webserver of choice (nginx, apache, etc) to host the static files.

We recommend to not cache the index.html file as it is the only file that isn't versioned. All other dependencies the index.html links to are versioned and can be cached indefinitely on all proxies.

Keep Cross Origin Resource Sharing in mind when deploying to production.

TODOs

  • Test CI should work on dist files
  • Try to implement grunt-bower plugin
  • See if we still need this custom reload task

Contact

For more information on AngularJS please check out http://angularjs.org/ For more information about angular-super-seed check out http://github.com/Kunstmaan/angular-super-seed/

Created by @daanporon and @spobo with the help of @sambego and @KimGressens. (loosely based on angular-seed)