Skip to content

Instantly share code, notes, and snippets.

@leostera
Created August 19, 2013 15:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save leostera/6270644 to your computer and use it in GitHub Desktop.
Save leostera/6270644 to your computer and use it in GitHub Desktop.
CleverStack ngSeed Blog Post
# 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](http://www.grunt-docular.com/).
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](http://www.chaijs.com) and [Jasmine](http://www.jasmine.com). 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](http://screencast.com/t/OBxfgoM26T).
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