Angular.js

Grunt.js

Yeoman

Node.js

Lunch and Learn @ Union Pacific

These slides are up on GitHub!

mrkelly/up-angular

Today's Objective

Share our experience building a production application using Angular JS

Many of the topics covered are universal to any JS dev

We love questions, don't be shy..you cannot derail us (challenge)

About Us

We are NOT experts, just write a ton of code.

We're ALL noobs

Project Layout

Objectives

  • Familiar for enterprise Java devs
  • Clear separation of concerns
  • Compiled code away from written code
  • Obvious (please)
  • Have our favorite libs play together nicely

Let's take a look

Mixtape on Github

Yeoman generators

  • Spearheaded by famous Googlers (Paul Irish and Addy Osmani)
  • Easy to write custom generators to fit your project
  • Helps keep the project structure consistent
  • Can be published as NPM Modules
generator-mixtape

Build Process

  • Automate Everything!!
  • Minimize developer interaction (just write the code)
  • Discover devs' complaints and try to eliminate them

Grunt

  • The JavaScript Task Runner
  • A ton of tasks already written to do most anything
  • Easy to extend and write your own tasks
  • Gruntfile.js (let's take a look)

Watch Task


// A task that runs in the background 'watching' for changes to code.
watch : {
    options : {
        livereload: true
    },
    client: {
        files: [
            'client/src/**/*.js',
            'client/test/**/*.js',
            '<%= assetsDir %>/templates/**/*.html'
        ],
        tasks: ['assemble', 'karma:unit:run', 'karma:e2e:run']
    },
    server : {
        files: [
            'test/**/*.js',
            'app/**/*.js'
        ],
        tasks: ['mochacli']
    },
    views : {
        files: [
            'app/views/**/*.jade',
            '<%= assetsDir %>/less/**/*.less'
        ],
        tasks: ['assemble']
    }
}

Server Task

  • Simple custom Grunt task to serve our index.html locally
  • Gives us 'environments' to run our code in different phases
  • Uses nodemon to monitor for changes (restarts the server)
  • Just a wrapper around the CLI for nodemon

JSHINT

  • Since JavaScript is a dynamic language, it's impossible to get static compilation feedback
  • Check that your code follows best practices
  • Add settings to tweak the linting to your tastes
  • Helps keep the code consistent among the team

LESS

  • CSS preprocessor to make life a little easier
  • Adds variables and mixins
  • Twitter Bootstrap is written in LESS

Minification and Uglification

Uglification is the optimization/compression/minimization of source code. For JavaScript, we use UglifyJS2

  • Parser produces abstract syntax tree
  • AST is optimized into a smaller one by
    • Applying optimization transforms
    • Mangling variables
    • Analyzing the scope
  • As an added benefit: your source code is obfuscated

Minification Example

Minification results on a real project

  • Original  2611949 bytes (2.49MB)
  • Minified  996966 bytes (973.5KB)
  • Gzipped  170552 bytes (166.5KB)
  • 15:1 Compression ratio

Special Considerations

Because of mangling, Angular dependency injection and "Pretotyping" no longer works and leads to the infamous:


Uncaught Error: Unknown provider: aProvider <- a
  • Convert all modules and components to string argument style
  • Lets take a look

Templates

Templates are static, so why not provide them as a compiled resource? This is where grunt-angular-templates comes in.

  1. Glob match files and directories
  2. The $templateCache service is then preloaded with the static content
  3. Template preload file is then uglified with the rest of the source

Other useful Grunt plugins

3rd Party Libraries

moment.js

Arguably the best date formatting library on the planet

  • Formatting
  • Internationalization
  • Calculations
  • Fuzzy dates

HTML5 Shims and Polyfills

A long list of libraries for providing standard HTML4 and HTML5 capabilities in "web browsers" (IE)

  • SVG
  • Form Elements
  • Web Sockets
  • Browser state

respond.js

respond.js is a CSS3 polyfill for media queries.

  • Automatic browser detection
  • Fast and lightweight
  • Works great with Twitter Bootstrap
  • Has a few caveats

Lo-dash

"A utility library delivering consistency, customization, performance, and extras."

  • High performance (in some cases beats browser implementations)
  • Has most utility functions you would typically create yourself

Twitter Bootstrap

One of the best base stylesheets and a great place to start with new applications

  • Responsive
  • Written in LESS so its easily extendable
  • Bootstrap 3 supports browsers newer than internet explorer 7
  • Fast paint and rendering times
  • Some of the best plugin support

Automated Testing

  • Tests should run automatically during build process
  • Should be very easy to write
  • Logical placement of tests within code

Mocha

  • Behavior driven development
  • Runs in the browser and on the server (Node)

Chai

  • Assertion library
  • Can actually be used in real code

  expect(foo).to.be.a('string');
  expect(foo).to.equal('bar');
  expect(foo).to.have.length(3);
  expect(tea).to.have.property('flavors').with.length(3);

Check out this  awesome talk by Rebecca Murphey at JSConf 2013

Angular Scenarios

  • End to End tests
  • Similar to Selenium testing
  • Created by the Angular team so they are 'Angular-aware'
  • Navigate through the browser and check for correct behavior
  • Jasmine syntax (very similar to Mocha)

Karma Integration

Spectacular test runner from the Angular JS team

  • Run your tests in multiple browsers at once
  • simple configuration
  • 'Debug' mode to see your tests in action in the browser

Continuous Integration

Jenkins

  • Works out of the box
  • Uses development tools
  • Run commands as you would locally

Git source control

  • Building a single branch
  • Building multiple branches
  • Special considerations with the workspace

The Process

  • Install NPM and Bower packages
  • Run the assembly task
  • Test
  • Record the JUnit test results

More on Tests

More than likely your CI will be running on a headless OS. How do you run end-to-end tests with no display?

PhantomJS

Phantom JS is a headless WebKit browser

  • Works out of the box
  • Scriptable API
  • Performance reporting
  • Not comparable with Firefox
  • It's a WebKit port, not a real browser

Xvfb

X Virtual Frame Buffer provides a virtual X11 server on a headless device for GUI applications.

  • Color depth and resolutions are customizable
  • Easy to install and configure
  • Test with Chrome, Firefox, etc.
  • *nix only

Examples

Angular.js

  • Teaching the browser new tricks
  • Dependency Injection
  • A bit of a learning curve (but not much)
  • Change the model, let Angular do the rest

Modules

  • Small packages of functionality
  • Helps keep the application decoupled and promotes re-use
  • If minifying your code, make sure to use the array syntax(or use ng-min)

Directives

  • The most powerful part of Angular
  • Meta-framework that you can use to create a DSL for the browser
  • Great talk by Misko

UI Router

  • Cool project by theAngular UI devs
  • Allows for nested views
  • Provides a complete state machine linked to your urls

ng-boilerplate

  • Very cool new project
  • Takes a different approach to code organization
  • Modules are self-contained (feels very Web Component-ish)

Let's take a gander

ng-boilerplate on Github

Conclusion

Questions