Skip to content

Instantly share code, notes, and snippets.

@iki
Forked from leostera/ngseed.post
Created August 27, 2013 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iki/6352623 to your computer and use it in GitHub Desktop.
Save iki/6352623 to your computer and use it in GitHub Desktop.

CleverStack

Angular Seed

YAAS (Yet Another Angular Seed)

While know about the existence of ng-boilerplate, the angular-app repo on Github, or even Yeoman and it's angular-generator, none of those really fit the bill when it comes to structuring a medium to large application as it often is the case here at Clevertech.

This is not yet another angular seed: this is the collaborative effort of open source enthusiasts to solve the most of the problems in AngularJS development. Yes, we took the liberty of adding a bit of a bleak packaging but that allows us for dead-easy installing, upgrading and extending.

Let's dive into it.

A proper look into the AngularJS seed:

As our main goal, besides solving some common problems we are going to talk about in a minute, we set that the seed:

  • Must provide solutions to common problems

  • Must be easily configurable

  • Must facilitate good practices

Solutions to common problems

Server running, Authorization, Authentication, RESTful resources, preprocessors support, script loading, dependency management, build systems, documentation generation, unit testing, functional testing.

Those are some of the common problems we successfully solved, and they indeed vary from very high level solutions to some closer to the metal ones.

Server running

In all honesty, I think we are doing a great job here. With just grunt server you get 3 servers running (one of them with LiveReloading):

  • Development Server @ localhost:9000
  • Production Server @ localhost:9009
  • Documentation Server @ localhost:9999
  • Functional Testing Server @ localhost:9090/test/e2e/runner.html

And it's in our plan to include a Unit Testing Server that will run at localhost:9090/test/unit/runner.html or a similar address.

All ports and addresses are easily configurable from your Gruntfile.js file.

Auth with $auth

The $auth provider, and the role it has within this seed, is to facilitate the tedious process of checking for a valid session, redirecting to a login, redirecting again to the page if necessary.

It's based around the $module:actionStatus event naming pattern with some examples being $auth:loginSuccess for when the login was successful or $auth:loginFailure otherwise.

It would be tempting to listen to this events since they are being $broadcasted from the $rootScope but we offer a better way for this: you can instead configure the handlers directly from a .config block using the $authProvider.

Also, using the aforementioned mechanism makes it very straightforward to change from a login page to a login modal that is available site-wide and doesn't require redirection login. Thou we are yet to experiment more with this approach.

RESTful $resourceFactory

You and I have both experienced having to duplicate files to create the most simple $resource based services due to the lack of a more elegant method. That is why I have created the $resourceFactory. As a service it allows you to configure resources at runtime. We are still working on this so stay tuned for news!

Preprocessor Support

Since we are building our task automation using Grunt, any of the available preprocessors for Grunt are easily pluggable. We preffer vanilla JavaScript, plain HTML and a little bit of LESS. Just hack your way thru the Gruntfile.js, which if you have used yeoman before you'll feel right at home.

Script Loading and Dependency Management

From all the options out there, we chose RequireJS since it was the one that best adapted to the structure, it turned out, we needed; regardless of the environment.

We have a specific config file for the unit testing environment.

Build System

As Grunt runs our tasks, our build process is simple yet incredibly flexible and extendible. Just run grunt build and it will:

  • clean the previous build,
  • prepare everything for usemin,
  • compile the less files,
  • minify images,
  • minify the css and the html,
  • copy everything to the dist folder,
  • minify the angularjs code,
  • prepare the requirejs build process,
  • timestamp the filename,
  • update all the html with the timestamped file,
  • and builds the docs.

All that in around 11.28 seconds (on the latest MacBook Air 13-inches with a 1.3GHz Intel Core i5). On the average development desktop computer it will most likely be down to around 6 or less; in a dedicated CI box it will take blink of an eye.

Documentation Generation

At Clevertech we feel the urge to document. Documentation helps us understand faster what is going on with the code at a higher level, helps us share code without relying on anybody to explain it, helps us to maintain and extend code more quickly and with more ease. This, amongst other reasons, is why we include docular, and we do our best to document all what we include by default and help you document what you build with precision and ease.

The process of documenting is fairly easy as we stick with docblocks. The syntax for them can be found at Docular's website.

Building the documentation is an easy process as well. Just run grunt docs (or grunt build, which includes building the docs as part of the process) and in just above a second[1] you should get it built and ready to use. Browse your docs by running grunt server' and opening localhost:9999`.

[1] Under a mid 2013 MacBook Air 13-inches running a 1.3GHz Intel Core i5 the bundled documentation takes in average 1.20 seconds

Unit Testing

We like karma, we think it's elegant, fast and simple to use. We like it so much we don't even wrap it with grunt. You can run your unit tests from the console with karma start --single-run or if you'd rather the faster approach just start the karma server with karma start (or karma start &) and do karma run whenever you want to run your tests.

Unit tests are written with Chai and Jasmine. Anyone familiar with mocha and should (or expect) will be right at home.

If you have a BrowserStack account, you can also run this tests on BrowserStack with virtually no changes. Well, just one: in your karma.conf.js file set the browser to one of the BrowserStack: prefixed ones. Then add your credentials to the .browserstack.json file and your key to the scripts/bs-tunnel-karma.sh file and run npm run-script bs-tunnel-karma. Make sure the tunnel is open and you're free to run your tests just as before[2].

[2] I would advise thou to run them with karma start and karma run because the tunneling makes the bootstrapping quite slower.

Functional Testing

This was a hard one. It took a couple days to get it together and we ended up without command line execution for the moment, but we are still working on it.

Using FuncUnit (which uses Syn) we were able to run tests at a really high level using a test runner (by default accessible at localhost:9090/test/e2e/runner.html) as you can see in this video.

We are currently looking for the best way to write this tests as they can easily get messy and fall into the callback hell. I will be blogging about this sooner than later.

We are also actively working on BrowserStack support.

Easily Configurable

We set the bar expecting anyone, beginner or expert, to quickly set everything up and start working on the stuff that matters. This means a highly configurable environment with sensible default values.

Gruntfile.js

As Grunt was the foundation block for task automation, most of the configuration is still kept within a Gruntfile.js at the root of the project structure. Within it you will find:

  • docular: the documentation config,
  • watch: the file watching config,
  • requirejs: the requirejs config (also uglifyjs config),
  • connect: quickly configure the servers

As well as some tasks:

  • server: the task that runs all the servers and setups the live reloading,
  • build: the task that builds the whole project and generates the documentation,
  • default: basically build and then server

And some utility functions defined at the top that help the servers do their job.

bower.json and .bowerrc

We use Bower to manage front-end dependencies. This is the typical bower configuration file and needs no further explanation.

.browserstack.json and scripts/bs-tunnel-*.sh

Both this files need only your BrowserStack credentials.

karma.conf.js

This is the typical karma configuration file. Feel free to make as many copies of this one as you need and tune them to your needs: BrowserStack running, file watching, single browser, headless browsers, multiple browsers, different logging levels, CI reporters, et cetera. Refer to the karma documentation for more options.

Facilitate Good Practices

  • TDD/BDD
  • CI/CD
  • DevTools UX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment