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.
- Feature based modules
- Environment specific configuration
- State based routing (AngularUI Router)
- Configurable routing (states.json in feature folders)
- Unit (karma + mocha with sinon & chai) and e2e (protractor + cucumber & chai-as-promised) testing preconfigured
To get started you can simply clone this repository and install the necessary dependencies:
Clone the angular-seed repository using git:
git clone https://github.com/Kunstmaan/angular-super-seed cd angular-super-seed
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.
- AngularJS and other 3rd party libraries are managed via bower.
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
To easily start this web server with the standard development environment:
It will automatically open your browser and navigate to the right url.
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.
brew install phantomjson OS X).
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
- Creates a template cache.
- Generates the config app, you can specify the environment using
APP_ENV=prod grunt buildwill build the application using the production configuration.
- Prefers minified dependencies if they are stored next to the original dependencies. Will take
- File revisioning.
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
- 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
It also contains some functions to invoke keypresses and throw events which sometimes go wrong with browserTrigger (which is also included in the
Even if jshint fails the tests will still run with
- This will generate cobertura coverage reports.
You can ignore files in your coverage by placing
ci:coverage:excludesomewhere 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
- The tests are located in
- 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.
- Test CI should work on dist files
- Try to implement grunt-bower plugin
- See if we still need this custom reload task