'yo, grunting in a bower!'


... or how I learned to  stop worrying, 
start  flying,
develop with flow,
and publish my tested front-end code

Samuli Ulmanen
(Full Stack guy playing ) Web Developer 
Rovio Entertainment Ltd.

Yo - the flying start

 empty directory

why yo?




  • prerequisite is to know js 
  • simple to write 
  • get to the flying start you want
  • if you don't need the details right now but want to lint, concat, minify, test, gzip, spritesheet, less || sass || stylus, coffee, jasmine, spritesheets ... you get the idea.

Yo - project scaffolding


  • package your build
  • publish  for all to use
  • evolve as you go on
  • bring the focus to code not process




how, yo?




> sudo npm install -g yo 
> mkdir my-project && cd my-project
> yo angular 

Yo my generator




  • npm install generator-generator
  • npm search generator-my-generator  
  • start w/ generator-generator
  • write and test code
  • npm publish

 > mkdir generator-fabulous && cd generator-fabulous && yo generator

yo what is this I don't even ...



Tale of a generator




easy way to separating an angular module 
from your code
 https://github.com/sulmanen/generator-angular-module

So now we're FLying?


... enter 




Why on earth?


You reap what you sow and ...


There are practical little things in housekeeping that no man really understands 
-Eleanor Roosevelt




Any grunters in the house ?


HI there




one of many Task runners

but 

this one has 
a wide ecosystem
api and scaffolding for your tasks


Get set up




grunt >= 0.4 
> sudo npm install -g grunt-cli> cd my_project && npm install grunt --save-dev



...with CI server


> npm install grunt-cli && grunt --save-dev




Favorite grunt tasks?



some of mine

  • grunt-contrib-watch
  • grunt-usemin
  • grunt-bower-task
  • grunt-angular-prangler

watch



 watch: {
            options: {
                atBegin: true,
                livereload: true
            },
            app: {
                files: ['app/**/*', 'Gruntfile.js'],
                tasks: ['short']
            }
        }
  • keep tasks short and fast
  • install livereload extension

Usemin

 useminPrepare: {            html: 'tmp/index.html'
 },
 usemin: {
            html: ['tmp/*.html'],
            css: ['tmp/app/css/vendor/**/*.css'],
            options: {
                dirs: ['tmp']
            }
 }
  • prepare 
    • scan index.html for entries
    • auto-configure tasks
  • usemin 
    • replace link to optimized file in index.html
  • copy files to staging before running this y'all

... there's never enough time


 > npm install time-grunt --save-dev

 module.exports = function(grunt) {
    // dont need no time plugin on CI server
    if (!CI_SERVER) {
        require('time-grunt')(grunt);
    }


optimize




  1. concise globbing
  2. load task deps when task is run



concise globbing

  • configure task file globbing so it's as concise as possible
  • fastest performance listing every file by hand

load deps JIT


 was doing ...
 require('load-grunt-tasks')(grunt, ['grunt-!(cli)']);

am doing ...
 grunt.registerTask('short', [], function() {
        grunt.loadNpmTasks('grunt-contrib-stylus');
        grunt.loadNpmTasks('grunt-contrib-clean');
        grunt.loadNpmTasks('grunt-angular-prangler');
        grunt.loadNpmTasks('grunt-contrib-copy');
        grunt.task.run('clean:all', 'stylus', 'lint-short', 'prangler', 'copy:stage', 'copy:main');
    });

FuTURE




v0.5 node-task







 http://weblog.bocoup.com/tearing-grunt-apart/



What if I wanna use make?

... go for it!
... but know what you're missing out on.

e.g. AngularJS just switched from rake 
to grunt.js to 
attract more developers




Ok, so I wanna publish my code

BOWER





YAPM


  • not to mix front and backend deps
  • web has much freedom so be flexible
  • everyone doesn't use common-js modules, (browserify if you want to but that's another story )




GEt started

 > bower init

bower.jason

 {
  "name": "stats",
  "version": "0.0.1",
  "authors": [
    "Samuli Ulmanen <samuli.ulmanen@rovio.com>"
  ],
  "private": true,
  "description": "Stats",
  "main": "stats.js",
  "keywords": [
    "analytics",
    "scheduler",
    "angular"
  ],
  "license": "All rights reserved",
  "dependencies": {
    "lodash": "2.4.0",
    "angular": "1.2.5",
    "angular-resource": "1.2.5",
    "angular-route": "1.2.5",
    "jquery": "2.0.3",
    "momentjs": "2.1.0",
    "later":"",
    "bootstrap-javascript": "2.3.2",
    "prettycron-scheduler-fork":"",
    "node-cron-sulmanen-fork":"1.0.4"
  },
  "devDependencies":  {
    "angular-mocks": "1.2.5",
    "angular-scenario": "1.2.5"
  }
}

bower install 

pull in the whale


 > bower install

or

 "scripts": {
    "postinstall": "./node_modules/.bin/bower install"
  } thnx @quinnirill

main in bower.json


  > bower list --paths
 {
  "angular-mocks": "bower_components/angular-mocks/angular-mocks.js",
  "angular-resource": "bower_components/angular-resource/angular-resource.js",
  "angular-route": "bower_components/angular-route/angular-route.js",
  "angular-scenario": "bower_components/angular-scenario/angular-scenario.js",
  "angular": "bower_components/angular/angular.js",
  "bootstrap-javascript": "bower_components/bootstrap-javascript/bootstrap.js",
  "lodash": "bower_components/lodash/dist/lodash.compat.js",
  "momentjs": "bower_components/momentjs/moment.js",
  "prettycron-scheduler-fork": "bower_components/prettycron-scheduler-fork/prettycron.js",
  "node-cron-sulmanen-fork": "bower_components/node-cron-sulmanen-fork/lib/cron.js",
  "jquery": "bower_components/jquery/jquery.js",
  "later": "bower_components/later/later.js"
}



Main...

  • make sure the file you want to include is in the list
  • if not, fork and make your own bower.json or wait

grunt bower task


 https://github.com/yatskevich/grunt-bower-task
 src: {
                options: {
                    targetDir: './app/js/vendor',
                    // this will strip component name
                    layout: 'byType',                    install: false,
                    verbose: false,
                    cleanTargetDir: true,
                    cleanBowerDir: false,
                    bowerOptions: {
                        production: true
                    }
                }
            }

What to do with code 

you can't publish



  • use internal registry

 > npm install bower-registry

.bowerRC



 {
  "directory": "bower_components",
  "json": "bower.json",
  "registry": {
    "register": "http://hawk:8888",
    "search": [
      "https://bower.herokuapp.com",
      "http://hawk:8888"
    ]
  }
}




Q's

Made with Slides.com