Home

Awesome

angular-grunt-coffeescript

A Seed project for large CoffeeScript AngularJS projects

Motivation

But I code in Javascript!

All of the conventions and lessons-learned demonstratred here can be applied to a Javascript-based project.

Features

Building and Running

Initial setup

  1. Ensure that you have node, npm, grunt, and coffeescript installed and in your path
  2. Clone this repository
  3. Run npm install to pull down all build-time dependencies

Start server and watch for changes

The default grunt task will start the server and watch for changes. When changes are made the project is rebuilt, pushed to the server, and all unit tests are run through Testacular.

Build Output

When you run the default Grunt task, you will see this output in your project's directory. target/build/main is served by the webserver.

target/build
  main/              # all application files and code
    index.html       # your old friend index.html
    js/
      app.js         # all of your application's code, concatenated
      lib.js         # all 3rd party library code, concatenated
    style/
      app.css        # all of your application's css, concatenated
      lib.css        # all 3rd party library css, concatenated
    ...              # a directory per 'package', with all the static files (html, imgs, etc)
  test/              # all tests

Conventions

All of these are demonstrated in the example code.

Directories & Files

src/             
  main/              # application root
    index.html       # good ol' index.html
    app/             # contains all application files
      app.coffee     # handles routing, module wiring, and bootstrapping
      ...            # a directory per 'package'.  Described later
    lib/             # all 3rd party code
      ...            # a directory per 3rd party lib
  test/              # all test files and code
    config           # testacular configs
    lib              # test-time libraries
    ...              # directory per package, generally with a Spec file per package
  profile/           # environment-specific overrides.  See 'Profiles'
    prod             # overrides for prod env
      ...
    dev              # overrides for dev env, the default
      ...

Packages

A 'package' is a loose term I'm using for a grouping of related artifacts. Best explained by example: o

The structure you use for these groupings is up to you, but I've found that the 'xxxView' and 'common' structure has worked very well.

Modules and 'Angular Items'

An 'Angular Item' is, for instance, a Vaule, Factor, Directive, Filter, Controller, etc. There's no good term for these things, unfortunately.

Because we're using dependency injection, we don't need to use any javascript namespacing. Everything in CoffeeScript is in an anonymous function and so never global, and everything we need we make sure is available in a module.

The key, then, becomes the naming convention we use for both our modules and the Angular Items.

Having one module per Item makes wiring easy - We just list all of our modules in app.coffee.

Misc Conventions

Profiles

Under src/profiles is a directory per 'profile' (currently dev and prod, but add as many as you need). During the build, these directories are overlayed directly on top of the main code, overriding anything that may be there. By default the build will use the 'dev' profile.

envProvider

The common.services.envProvider module is where most of the environment-specific aspects of your application will be defined. At the very least each environment must provide an instance of this module. The module is responsible for:

If you take a look at the prod module, you'll see that the provider simply instantiates the service, and the service provides the production URL.

The dev module, however, uses $httpBackend to act as a fake server. Since $httpBackend is set up in a run block, we put the setup code in the appRun function.

Having the ability to run custom code in the application module's config and run blocks as well as having an injectable service that abstracts away all environment specific aspects of your application gives you the option to set up your application's enviroments in whatever ways you need.

To run an enviroment specific build, add an profile flag to your command line as follows:

grunt --profile prod --config grunt.coffee

Everything Else

A distribution build minifies your js and css. Run grunt --config grunt.coffee dist

TODOs

Thanks

Some of the ideas here are my own but many are built upon the work of others: