Client Side Assets



Thursday, 13 December 12
Thursday, 13 December 12
npm for the front-end




Thursday, 13 December 12
> bower install jquery




Thursday, 13 December 12
> bower install jquery
    bower cloning git://github.com/components/jquery.git
    bower caching git://github.com/components/jquery.git
    bower fetching jquery
    bower checking out jquery#1.8.1
    bower copying /Users/timoxley/.bower/jquery




Thursday, 13 December 12
component.json


    {
      "name": "myProject",
      "version": "1.0.0",
      "main": "./path/to/main.css",
      "dependencies": {
        "jquery": "~1.7.1"
      }
    }




Thursday, 13 December 12
component.json


    > bower install
    bower cloning git://github.com/components/jquery.git
    bower cached git://github.com/components/jquery.git
    bower fetching jquery
    bower checking out jquery#1.7.1
    bower copying /Users/timoxley/.bower/jquery




Thursday, 13 December 12
> bower update
    bower cloning git://github.com/components/jquery.git
    bower cached git://github.com/components/jquery.git
    bower fetching jquery
    bower checking out jquery#1.7.2
    bower copying /Users/timoxley/.bower/jquery




Thursday, 13 December 12
components
                           by TJ Holowaychuk




Thursday, 13 December 12
modular… components.




Thursday, 13 December 12
> component install component/jquery




Thursday, 13 December 12
single responsibility principle




Thursday, 13 December 12
“Have you ever seen a great jQuery
     plugin and thought to yourself “damn!
     I’m using MooTools!” or perhaps the
     other way around?”




Thursday, 13 December 12
“That highlights the problem right
     there, we should have no “jQuery
     plugins”, no “Dojo modules”, just simply
     “components” that we can all consume.”




Thursday, 13 December 12
“Components could then utilize these
     smaller, more modular dependencies to
     perform tasks.”




Thursday, 13 December 12
“Instead of requiring jQuery as a
     dependency to convert a string of HTML
     into elements, one could simply add
     domify as a dependency and invoke
     domify(html).”




Thursday, 13 December 12
“…ubiquitous libraries like jQuery will
     eventually be a thing of the past and
     fragmentation will hopefully decrease.”
                                               –
     TJ Holowaychuk




Thursday, 13 December 12
microjs meets npm




Thursday, 13 December 12
Thursday, 13 December 12
Thursday, 13 December 12
Thursday, 13 December 12
Thursday, 13 December 12
Thursday, 13 December 12
Thursday, 13 December 12
•visionmedia/superagent           •component/history                •component/noticon
    •visionmedia/page.js              •component/moment                 •component/zepto
    •jprichardson/string.js           •forbeslindesay/booting-sub-nav   •component/escape-regexp
    •guille/ms.js                     •juliangruber/stream              •component/jquery
    •component/domify                 •component/t                      •component/batch
    •component/emitter                •component/grow                   •solutionio/countdown
    •component/tip                    •component/dom                    •componitable/editable
    •component/dialog                 •component/matches-selector       •juliangruber/span
    •component/notification            •component/color-parser           •component/underscore
    •visionmedia/bytes.js             •component/inherit                •solutionio/backbone
    •component/bus                    •component/select                 •solutionio/async
    •component/overlay                •component/map                    •component/buttonset
    •component/autoscale-canvas       •component/escape-html            •colinf/datecalc
    •component/popover                •component/pager                  •retrofox/to-object
    •component/event                  •component/bind                   •componitable/format-number
    •component/confirmation            •component/more                   •retrofox/toolkit
    •component/confirmation-popover    •component/trim                   •component/aurora-calendar
    •component/popup                  •component/object
    •component/menu                   •component/removed
    •component/clipboard              •component/pie
    •jamesarosen/ember-progressbars   •component/inserted
    •component/suggest-email          •component/mime
    •component/clipboard-dom          •component/sketch
    •component/cookie                 •component/indexof
    •component/path                   •component/convolve
    •component/path-to-regexp         •component/preloader
    •component/color-picker           •component/piecon
    •component/within-document        •component/json
    •component/classes                •component/pad
    •component/upload                 •component/confirmation-
    •component/file                     notification
    •component/touchit                •component/dropdown
    •component/color                  •component/relative-date
    •component/thumb                  •component/type
    •component/calendar               •component/favicon
    •component/url                    •component/counter
    •component/query-string           •component/assert
    •component/progress-notification   •component/states
    •component/progress               •component/countries
    •forbeslindesay/ajax              •component/regexps
    •component/dropload               •component/style

Thursday, 13 December 12
Thursday, 13 December 12
                           GRUNT
Grunt is a task-based
               command line build
               tool for JavaScript
               projects.

Thursday, 13 December 12
Similar Tools
                   • GNU Make     • Sprockets
                   • Apache Ant   • + many more
                   • Jake
                   • Cake
                   • Rake
                   • Buildr

Thursday, 13 December 12
What does a grunt file
               look like?


Thursday, 13 December 12
module.exports = function(grunt) {

      // Project configuration.
      grunt.initConfig({
        lint: {
          all: ['grunt.js', 'lib/**/*.js', 'test/**/*.js']
        },
        jshint: {
          options: {
            browser: true
          }
        }
      });

      // Load tasks from "grunt-sample" grunt plugin installed via Npm.
      grunt.loadNpmTasks('grunt-sample');

      // Default task.
      grunt.registerTask('default', 'lint sample');

    };




Thursday, 13 December 12
module.exports = function(grunt) {
      grunt.initConfig({
        handlebars: {
          all: {
            src: "src/templates/",
            dest: "public/js/templates.js"
          }
        },
        less: {
          all: {
            src: 'src/less/application.less',
            dest: 'public/css/application.css'
          }
        },
        concat: {
          app: {
            src: ['src/app/*.coffee'],
            dest: 'public/js/main.coffee'
          }
        },
        watch: {
          all: {
            files: ["src/*",
                   "src/**"],
            tasks: "default"
          }
        },
        coffee: {
          all: {
            src: ["public/js/main.coffee"],
            dest: "public/js",
            options: {
              bare: false
            }
          }
        }
      });

      grunt.loadNpmTasks("grunt-handlebars");
      grunt.loadNpmTasks("grunt-coffee");
      grunt.loadNpmTasks("grunt-less");
      return grunt.registerTask("default", "handlebars concat coffee less");
    };


Thursday, 13 December 12
module.exports = function(grunt) {

      // Project configuration.
      grunt.initConfig({
        meta: {
          version: '0.1.0',
          banner: '/*! App Name - v<%= meta.version %> - ' +
            '<%= grunt.template.today("yyyy-mm-dd") %>n' +
            '* THIS FILE IS GENERATED BY GRUNT. DO NOT MODIFY MANUALLYn' +
            '* http://app/n' +
            '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +
            'Company Inc.; */'
        },
        lint: {
          files: ['grunt.js', 'frontend/src/app.js', 'frontend/src/models/*.js', 'frontend/src/collections/*.js', 'frontend/src/views/*.js', 'frontend/src/router.js', 'frontend/spec/**/*.js', 'frontend/src/statechart.js']
        },
        concat: {
          libs: {
            src: ['<banner:meta.banner>',
                  'frontend/src/vendor/jquery-1.7.2.min.js',
                  'frontend/src/vendor/underscore-min.js',
                  'frontend/src/vendor/backbone.js',
                  'frontend/src/vendor/stativus.js',
                  'frontend/src/vendor/handlebars.runtime.js',
                  'frontend/src/vendor/moment-1.6.2.js'
            ],
            dest: 'public/js/libs.js'
          },
          tribe: {
            src: ['<banner:meta.banner>', 'frontend/src/app.js', 'frontend/src/models/*.js', 'frontend/src/collections/*.js', 'frontend/src/views/*.js', 'frontend/src/router.js', 'frontend/src/statechart.js'],
            dest: 'public/js/tribe.js'
          },
          css: {
            src: ['<banner:meta.banner>', 'frontend/css/reset.css', 'frontend/css/base.css', 'frontend/css/tribe.css'],
            dest: 'public/css/screen.css'
          }
        },
        min: {
          libs: {
            src: ['<banner:meta.banner>', 'public/js/libs.js'],
            dest: 'public/js/libs.min.js'
          },
          tribe: {
            src: ['<banner:meta.banner>', 'public/js/tribe.js'],
            dest: 'public/js/tribe.min.js'
          },
          templates: {
            src: ['<banner:meta.banner>', 'public/js/templates.js'],
            dest: 'public/js/templates.min.js'
          }
        },
        recess: {
          css: {
            src: ['public/css/screen.css'],
            dest: 'public/css/screen.min.css',
            options: {
              compress: true,
              noIDs: false
            }
          }
        },
        handlebars: {
          all: {
            src: 'frontend/src/templates',
            dest: 'public/js/templates.js'
          }
        },
        watch: {
          files: ['<config:lint.files>', 'frontend/css/*.css', 'frontend/src/templates/*.handlebars'],
          tasks: 'handlebars concat:tribe concat:css min:tribe min:templates recess'
        },
        jshint: {
          options: {
            curly: true,
            eqeqeq: true,
            immed: true,
            latedef: true,
            newcap: true,
            noarg: true,
            sub: true,
            undef: true,
            boss: true,
            eqnull: true,
            browser: true
          },
          globals: {}
        },
        uglify: {}
      });

      grunt.loadNpmTasks('grunt-handlebars');
      grunt.loadNpmTasks('grunt-recess');

      // Default task.
      grunt.registerTask('default', 'lint handlebars concat min recess');

    };




Thursday, 13 December 12
Running grunt



Thursday, 13 December 12
> grunt




Thursday, 13 December 12
Built-in Tasks
                   • concat -                  • lint - Validate files
                           Concatenate files.     with JSHint.

                   • min - Minify files
                           with UglifyJS.

                   • watch - Run
                           predefined tasks
                           whenever watched
                           files change.




Thursday, 13 December 12
Built-in Tasks
                   • server - Start a            • qunit - Run QUnit
                           static web server.      unit tests in a
                                                   headless PhantomJS
                   • init - Generate               instance.
                           project scaffolding
                           from a predefined      • test - Run unit tests
                           template.               with nodeunit.




Thursday, 13 December 12
Concatenate


    grunt.initConfig({
      concat: {
        dist: {
          src: ['src/intro.js', 'src/project.js', 'src/outro.js'],
          dest: 'dist/built.js'
        }
      }
    });




Thursday, 13 December 12
Lint


    grunt.initConfig({
      lint: {
        files: ['grunt.js', 'lib/*.js', 'test/*.js']
      }
    });




Thursday, 13 December 12
Lint
    grunt.initConfig({
      lint: {
        files: ['grunt.js', 'src/**/*.js', 'test/**/*.js']
      },
      jshint: {
        options: {
          curly: true,
          sub: true,
          undef: true
        },
        globals: {
          jQuery: true
        }
      },
    });




Thursday, 13 December 12
Minify


    grunt.initConfig({
      min: {
        dist: {
          src: ['vendor/*'],
          dest: 'public/libs.min.js'
        }
      }
    });




Thursday, 13 December 12
Watch

    grunt.initConfig({
      watch: {
        files: ['src/*.jade'],
        tasks: 'jade'
      },
      jade: {
        html: {
          src: ['src/*.jade'],
          dest: 'public'
        }
      }
    });




Thursday, 13 December 12
CoffeeScript makes for
               tidy Gruntfiles


Thursday, 13 December 12
module.exports = (grunt) ->
      grunt.initConfig
        handlebars:
          all:
            src: "src/templates/"
            dest: "public/js/templates.js"
        less:
          all:
            src: 'src/less/application.less'
            dest: 'public/css/application.css'
        concat:
          app:
            src: [
              'src/app/*.coffee'
            ]
            dest: 'public/js/main.coffee'
        watch:
          all:
            files: [
              "src/*",
              "src/**"
            ]
            tasks: "default"


      grunt.loadNpmTasks "grunt-handlebars"
      grunt.loadNpmTasks "grunt-less"

      grunt.registerTask "default", "handlebars concat less"




Thursday, 13 December 12
> grunt --config ./grunt.coffee




Thursday, 13 December 12
150+
               3rd Party Tasks


Thursday, 13 December 12
• contrib-clean -        • s3 - automate
                           Clear files and     moving files to/from
                           folders.           Amazon S3.

                   • cp - A Grunt plugin
                           for copying
                           directories
                           (recursively)

                   • md5 - generate
                           md5 filename

                   • shell - Run shell
                           commands




Thursday, 13 December 12
• contrib-handlebars            • contrib-jst -
                           - Precompile              Precompile
                           Handlebars                Underscore
                           templates to JST file.     templates to JST file.

                   • contrib-jade -                • mustache  -
                           Compile Jade files to      Concatenate
                           HTML.                     mustache template
                                                     files
                   • contrib-sass -
                           Compile Sass to CSS     • soy - Grunt task to
                                                     compile Soy /
                   • contrib-less -                  Closure Templates
                           Compile LESS files to
                           CSS.                    • compass - executes
                                                     compass



Thursday, 13 December 12
• mocha - Run Mocha
                           specs

                   • cucumber - Run
                           Cucumber.js

                   • vows - Run vows
                           tests

                   • benchmark -
                           Benchmarking

                   • strip - Remove
                           JavaScript
                           statements (like
                           console.log) from
                           your source code


Thursday, 13 December 12
• image-embed -               • rigger - Rigging
                           Embed images as         tasks for elegant
                           base64 data URIs        includes
                           inside your
                           stylesheets.

                   • smushit - Remove
                           unnecessary bytes
                           of PNG and JPG
                           using Yahoo
                           Smushit

                   • willitmerge - Check
                           if open Github pull
                           requests are merge-
                           able.



Thursday, 13 December 12
min: {
         app: {
           src: ['app/*'],
           dest: 'public/app.min.js'
         },
         libs: {
           src: ['vendor/*'],
           dest: 'public/libs.min.js'
         }
       }



    > grunt min:app
    > grunt min:libs


Thursday, 13 December 12
Creating Custom
               Plugins is Easy


Thursday, 13 December 12
> grunt init:gruntplugin




Thursday, 13 December 12
Running "init:gruntplugin" (init) task
    This task will create one or more files in the current directory, based on the
    environment and the answers to a few questions. Note that answering "?" to any
    question will show question-specific help and answering "none" to most questions
    will leave its value blank.

    "gruntplugin" template notes:
    The grunt plugin system is still under development. For more information, see
    the docs at https://github.com/cowboy/grunt/blob/master/docs/plugins.md

    Please answer the following:
    [?] Project name (grunt-plugin)
    [?] Description (The best sample grunt tasks ever.)
    [?] Version (0.1.0)
    [?] Project git repository (git://github.com/timoxley/grunt-plugin.git)
    [?] Project homepage (https://github.com/timoxley/grunt-plugin)
    [?] Project issues tracker (https://github.com/timoxley/grunt-plugin/issues)
    [?] Licenses (MIT)
    [?] Author name (Tim Oxley)
    [?] Author email (secoif@gmail.com)
    [?] Author url (none)
    [?] What versions of grunt does it require? (~0.3.9)
    [?] What versions of node does it run on? (*)
    [?] Do you need to make any changes to the above before continuing? (y/N) N

    Writing   .npmignore...OK
    Writing   bin/grunt-plugin...OK
    Writing   grunt.js...OK
    Writing   README.md...OK
    Writing   tasks/plugin.js...OK
    Writing   test/plugin_test.js...OK
    Writing   LICENSE-MIT...OK

    Initialized from template "gruntplugin".

    Done, without errors




Thursday, 13 December 12
// Load tasks and helpers from the "tasks" directory, relative to
    grunt.js.
    grunt.loadTasks('tasks');

    // Load tasks and helpers from the "grunt-sample" Npm-installed
    grunt plugin.
    grunt.loadNpmTasks('grunt-sample');




Thursday, 13 December 12
html5 boilerplate
                       +
                       grunt +
                       opinions =

Thursday, 13 December 12
node-build-script



Thursday, 13 December 12
bootstrap for grunt



Thursday, 13 December 12
• Concats / Compresses JS
                   • Concats / Compresses CSS
                   • Inline CSS imports via RequireJS
                   • Basic to aggressive html
                           minification (via [html-minfier][])

                   • Optimizes JPGs and PNGs (with
                           jpegtran & optipng)


Thursday, 13 December 12
• Renames JS/CSS to prepend a hash
                           of their contents for easier
                           versioning

                   • Revises the file names of your
                           assets so that you can use heavy
                           caching

                   • Updates your HTML to reference
                           these new hyper-optimized CSS +
                           JS files


Thursday, 13 December 12
• May rerun the build script on file
                           changes (grunt's watch task ❤)

                   • May automatically reload the page
                           in your browsers whenever watched
                           files change, through some
                           socket.io magic.




Thursday, 13 December 12
node-build-script
                       +
                       bower +
                       more opinions
                       =

Thursday, 13 December 12
Thursday, 13 December 12
By Paul Irish, Addy Osmani, Sindre Sorhus,
                       Mickael Daniel, Eric Bidelman, and the
                       Yeoman Community.




Thursday, 13 December 12
• HTML5 Boilerplate
               • Twitter Bootstrap
               • Twitter Bootstrap plugins
               • RequireJS
               • Support for ES6 Modules
               • Wraps bower
Thursday, 13 December 12
•        Lightning-fast scaffolding — Easily
                       scaffold new projects with customizable
                       templates (e.g HTML5 Boilerplate, Twitter
                       Bootstrap), AMD (via RequireJS) and more.

               •        Automatically compile CoffeeScript &
                       Compass — Our LiveReload watch process
                       automatically compiles source files and
                       refreshes your browser whenever a change
                       is made so you don't have to.




Thursday, 13 December 12
•        Automatically lint your scripts — All your
                       scripts are automatically run against jshint
                       to ensure they're following language best-
                       practices.

               •        Built-in preview server — No more having
                       to fire up your own HTTP Server. My built-
                       in one can be fired with just one command.

               •        Awesome Image Optimization — I optimize
                       all your images using OptiPNG and
                       JPEGTran so your users can spend less time


Thursday, 13 December 12
• Integrated package management — Need a
                       dependency? It's just a keystroke away. I
                       allow you to easily search for new packages
                       via the command-line (e.g., yeoman search
                       jquery), install them and keep them
                       updated without needing to open your
                       browser.

               • Support for ES6 module syntax —
                       Experiment with writing modules using the
                       latest ECMAScript 6 module syntax. This is
                       an experimental feature that transpiles
                       back to ES5 so you can use the code in all


Thursday, 13 December 12
•        PhantomJS Unit Testing — Easily run your
                       unit tests in headless WebKit via PhantomJS.
                       When you create a new application, I also
                       include some test scaffolding for your app.




Thursday, 13 December 12

Bundling Client Side Assets

  • 1.
  • 2.
  • 3.
    npm for thefront-end Thursday, 13 December 12
  • 4.
    > bower installjquery Thursday, 13 December 12
  • 5.
    > bower installjquery bower cloning git://github.com/components/jquery.git bower caching git://github.com/components/jquery.git bower fetching jquery bower checking out jquery#1.8.1 bower copying /Users/timoxley/.bower/jquery Thursday, 13 December 12
  • 6.
    component.json {   "name": "myProject",   "version": "1.0.0",   "main": "./path/to/main.css",   "dependencies": {     "jquery": "~1.7.1"   } } Thursday, 13 December 12
  • 7.
    component.json > bower install bower cloning git://github.com/components/jquery.git bower cached git://github.com/components/jquery.git bower fetching jquery bower checking out jquery#1.7.1 bower copying /Users/timoxley/.bower/jquery Thursday, 13 December 12
  • 8.
    > bower update bower cloning git://github.com/components/jquery.git bower cached git://github.com/components/jquery.git bower fetching jquery bower checking out jquery#1.7.2 bower copying /Users/timoxley/.bower/jquery Thursday, 13 December 12
  • 9.
    components by TJ Holowaychuk Thursday, 13 December 12
  • 10.
  • 11.
    > component installcomponent/jquery Thursday, 13 December 12
  • 12.
  • 13.
    “Have you everseen a great jQuery plugin and thought to yourself “damn! I’m using MooTools!” or perhaps the other way around?” Thursday, 13 December 12
  • 14.
    “That highlights theproblem right there, we should have no “jQuery plugins”, no “Dojo modules”, just simply “components” that we can all consume.” Thursday, 13 December 12
  • 15.
    “Components could thenutilize these smaller, more modular dependencies to perform tasks.” Thursday, 13 December 12
  • 16.
    “Instead of requiringjQuery as a dependency to convert a string of HTML into elements, one could simply add domify as a dependency and invoke domify(html).” Thursday, 13 December 12
  • 17.
    “…ubiquitous libraries likejQuery will eventually be a thing of the past and fragmentation will hopefully decrease.” – TJ Holowaychuk Thursday, 13 December 12
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
    •visionmedia/superagent •component/history •component/noticon •visionmedia/page.js •component/moment •component/zepto •jprichardson/string.js •forbeslindesay/booting-sub-nav •component/escape-regexp •guille/ms.js •juliangruber/stream •component/jquery •component/domify •component/t •component/batch •component/emitter •component/grow •solutionio/countdown •component/tip •component/dom •componitable/editable •component/dialog •component/matches-selector •juliangruber/span •component/notification •component/color-parser •component/underscore •visionmedia/bytes.js •component/inherit •solutionio/backbone •component/bus •component/select •solutionio/async •component/overlay •component/map •component/buttonset •component/autoscale-canvas •component/escape-html •colinf/datecalc •component/popover •component/pager •retrofox/to-object •component/event •component/bind •componitable/format-number •component/confirmation •component/more •retrofox/toolkit •component/confirmation-popover •component/trim •component/aurora-calendar •component/popup •component/object •component/menu •component/removed •component/clipboard •component/pie •jamesarosen/ember-progressbars •component/inserted •component/suggest-email •component/mime •component/clipboard-dom •component/sketch •component/cookie •component/indexof •component/path •component/convolve •component/path-to-regexp •component/preloader •component/color-picker •component/piecon •component/within-document •component/json •component/classes •component/pad •component/upload •component/confirmation- •component/file notification •component/touchit •component/dropdown •component/color •component/relative-date •component/thumb •component/type •component/calendar •component/favicon •component/url •component/counter •component/query-string •component/assert •component/progress-notification •component/states •component/progress •component/countries •forbeslindesay/ajax •component/regexps •component/dropload •component/style Thursday, 13 December 12
  • 26.
  • 27.
    Grunt is atask-based command line build tool for JavaScript projects. Thursday, 13 December 12
  • 28.
    Similar Tools • GNU Make • Sprockets • Apache Ant • + many more • Jake • Cake • Rake • Buildr Thursday, 13 December 12
  • 29.
    What does agrunt file look like? Thursday, 13 December 12
  • 30.
    module.exports = function(grunt){ // Project configuration. grunt.initConfig({ lint: { all: ['grunt.js', 'lib/**/*.js', 'test/**/*.js'] }, jshint: { options: { browser: true } } }); // Load tasks from "grunt-sample" grunt plugin installed via Npm. grunt.loadNpmTasks('grunt-sample'); // Default task. grunt.registerTask('default', 'lint sample'); }; Thursday, 13 December 12
  • 31.
    module.exports = function(grunt){   grunt.initConfig({     handlebars: {       all: {         src: "src/templates/",         dest: "public/js/templates.js"       }     },     less: {       all: {         src: 'src/less/application.less',         dest: 'public/css/application.css'       }     },     concat: {       app: {         src: ['src/app/*.coffee'],         dest: 'public/js/main.coffee'       }     },     watch: {       all: {         files: ["src/*", "src/**"],         tasks: "default"       }     },     coffee: {       all: {         src: ["public/js/main.coffee"],         dest: "public/js",         options: {           bare: false         }       }     }   });   grunt.loadNpmTasks("grunt-handlebars");   grunt.loadNpmTasks("grunt-coffee");   grunt.loadNpmTasks("grunt-less");   return grunt.registerTask("default", "handlebars concat coffee less"); }; Thursday, 13 December 12
  • 32.
    module.exports = function(grunt){   // Project configuration.   grunt.initConfig({     meta: {       version: '0.1.0',       banner: '/*! App Name - v<%= meta.version %> - ' +         '<%= grunt.template.today("yyyy-mm-dd") %>n' +         '* THIS FILE IS GENERATED BY GRUNT. DO NOT MODIFY MANUALLYn' +         '* http://app/n' +         '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +         'Company Inc.; */'     },     lint: {       files: ['grunt.js', 'frontend/src/app.js', 'frontend/src/models/*.js', 'frontend/src/collections/*.js', 'frontend/src/views/*.js', 'frontend/src/router.js', 'frontend/spec/**/*.js', 'frontend/src/statechart.js']     },     concat: {       libs: {         src: ['<banner:meta.banner>',               'frontend/src/vendor/jquery-1.7.2.min.js',               'frontend/src/vendor/underscore-min.js',               'frontend/src/vendor/backbone.js',               'frontend/src/vendor/stativus.js',               'frontend/src/vendor/handlebars.runtime.js',               'frontend/src/vendor/moment-1.6.2.js'         ],         dest: 'public/js/libs.js'       },       tribe: {         src: ['<banner:meta.banner>', 'frontend/src/app.js', 'frontend/src/models/*.js', 'frontend/src/collections/*.js', 'frontend/src/views/*.js', 'frontend/src/router.js', 'frontend/src/statechart.js'],         dest: 'public/js/tribe.js'       },       css: {         src: ['<banner:meta.banner>', 'frontend/css/reset.css', 'frontend/css/base.css', 'frontend/css/tribe.css'],         dest: 'public/css/screen.css'       }     },     min: {       libs: {         src: ['<banner:meta.banner>', 'public/js/libs.js'],         dest: 'public/js/libs.min.js'       },       tribe: {         src: ['<banner:meta.banner>', 'public/js/tribe.js'],         dest: 'public/js/tribe.min.js'       },       templates: {         src: ['<banner:meta.banner>', 'public/js/templates.js'],         dest: 'public/js/templates.min.js'       }     },     recess: {       css: {         src: ['public/css/screen.css'],         dest: 'public/css/screen.min.css',         options: {           compress: true,           noIDs: false         }       }     },     handlebars: {       all: {         src: 'frontend/src/templates',         dest: 'public/js/templates.js'       }     },     watch: {       files: ['<config:lint.files>', 'frontend/css/*.css', 'frontend/src/templates/*.handlebars'],       tasks: 'handlebars concat:tribe concat:css min:tribe min:templates recess'     },     jshint: {       options: {         curly: true,         eqeqeq: true,         immed: true,         latedef: true,         newcap: true,         noarg: true,         sub: true,         undef: true,         boss: true,         eqnull: true,         browser: true       },       globals: {}     },     uglify: {}   });   grunt.loadNpmTasks('grunt-handlebars');   grunt.loadNpmTasks('grunt-recess');   // Default task.   grunt.registerTask('default', 'lint handlebars concat min recess'); }; Thursday, 13 December 12
  • 33.
  • 34.
  • 35.
    Built-in Tasks • concat - • lint - Validate files Concatenate files. with JSHint. • min - Minify files with UglifyJS. • watch - Run predefined tasks whenever watched files change. Thursday, 13 December 12
  • 36.
    Built-in Tasks • server - Start a • qunit - Run QUnit static web server. unit tests in a headless PhantomJS • init - Generate instance. project scaffolding from a predefined • test - Run unit tests template. with nodeunit. Thursday, 13 December 12
  • 37.
    Concatenate grunt.initConfig({ concat: { dist: { src: ['src/intro.js', 'src/project.js', 'src/outro.js'], dest: 'dist/built.js' } } }); Thursday, 13 December 12
  • 38.
    Lint grunt.initConfig({ lint: { files: ['grunt.js', 'lib/*.js', 'test/*.js'] } }); Thursday, 13 December 12
  • 39.
    Lint grunt.initConfig({ lint: { files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'] }, jshint: { options: { curly: true, sub: true, undef: true }, globals: { jQuery: true } }, }); Thursday, 13 December 12
  • 40.
    Minify grunt.initConfig({ min: { dist: { src: ['vendor/*'], dest: 'public/libs.min.js' } } }); Thursday, 13 December 12
  • 41.
    Watch grunt.initConfig({ watch: { files: ['src/*.jade'], tasks: 'jade' }, jade: { html: { src: ['src/*.jade'], dest: 'public' } } }); Thursday, 13 December 12
  • 42.
    CoffeeScript makes for tidy Gruntfiles Thursday, 13 December 12
  • 43.
    module.exports = (grunt)->   grunt.initConfig     handlebars:       all:         src: "src/templates/"         dest: "public/js/templates.js"     less:       all:         src: 'src/less/application.less'         dest: 'public/css/application.css'     concat:       app:         src: [           'src/app/*.coffee'         ]         dest: 'public/js/main.coffee'     watch:       all:         files: [           "src/*",           "src/**"         ]         tasks: "default"   grunt.loadNpmTasks "grunt-handlebars"   grunt.loadNpmTasks "grunt-less"   grunt.registerTask "default", "handlebars concat less" Thursday, 13 December 12
  • 44.
    > grunt --config./grunt.coffee Thursday, 13 December 12
  • 45.
    150+ 3rd Party Tasks Thursday, 13 December 12
  • 46.
    • contrib-clean - • s3 - automate Clear files and moving files to/from folders. Amazon S3. • cp - A Grunt plugin for copying directories (recursively) • md5 - generate md5 filename • shell - Run shell commands Thursday, 13 December 12
  • 47.
    • contrib-handlebars • contrib-jst - - Precompile Precompile Handlebars Underscore templates to JST file. templates to JST file. • contrib-jade - • mustache - Compile Jade files to Concatenate HTML. mustache template files • contrib-sass - Compile Sass to CSS • soy - Grunt task to compile Soy / • contrib-less - Closure Templates Compile LESS files to CSS. • compass - executes compass Thursday, 13 December 12
  • 48.
    • mocha -Run Mocha specs • cucumber - Run Cucumber.js • vows - Run vows tests • benchmark - Benchmarking • strip - Remove JavaScript statements (like console.log) from your source code Thursday, 13 December 12
  • 49.
    • image-embed - • rigger - Rigging Embed images as tasks for elegant base64 data URIs includes inside your stylesheets. • smushit - Remove unnecessary bytes of PNG and JPG using Yahoo Smushit • willitmerge - Check if open Github pull requests are merge- able. Thursday, 13 December 12
  • 50.
    min: { app: { src: ['app/*'], dest: 'public/app.min.js' }, libs: { src: ['vendor/*'], dest: 'public/libs.min.js' } } > grunt min:app > grunt min:libs Thursday, 13 December 12
  • 51.
    Creating Custom Plugins is Easy Thursday, 13 December 12
  • 52.
  • 53.
    Running "init:gruntplugin" (init)task This task will create one or more files in the current directory, based on the environment and the answers to a few questions. Note that answering "?" to any question will show question-specific help and answering "none" to most questions will leave its value blank. "gruntplugin" template notes: The grunt plugin system is still under development. For more information, see the docs at https://github.com/cowboy/grunt/blob/master/docs/plugins.md Please answer the following: [?] Project name (grunt-plugin) [?] Description (The best sample grunt tasks ever.) [?] Version (0.1.0) [?] Project git repository (git://github.com/timoxley/grunt-plugin.git) [?] Project homepage (https://github.com/timoxley/grunt-plugin) [?] Project issues tracker (https://github.com/timoxley/grunt-plugin/issues) [?] Licenses (MIT) [?] Author name (Tim Oxley) [?] Author email (secoif@gmail.com) [?] Author url (none) [?] What versions of grunt does it require? (~0.3.9) [?] What versions of node does it run on? (*) [?] Do you need to make any changes to the above before continuing? (y/N) N Writing .npmignore...OK Writing bin/grunt-plugin...OK Writing grunt.js...OK Writing README.md...OK Writing tasks/plugin.js...OK Writing test/plugin_test.js...OK Writing LICENSE-MIT...OK Initialized from template "gruntplugin". Done, without errors Thursday, 13 December 12
  • 54.
    // Load tasksand helpers from the "tasks" directory, relative to grunt.js. grunt.loadTasks('tasks'); // Load tasks and helpers from the "grunt-sample" Npm-installed grunt plugin. grunt.loadNpmTasks('grunt-sample'); Thursday, 13 December 12
  • 55.
    html5 boilerplate + grunt + opinions = Thursday, 13 December 12
  • 56.
  • 57.
  • 58.
    • Concats /Compresses JS • Concats / Compresses CSS • Inline CSS imports via RequireJS • Basic to aggressive html minification (via [html-minfier][]) • Optimizes JPGs and PNGs (with jpegtran & optipng) Thursday, 13 December 12
  • 59.
    • Renames JS/CSSto prepend a hash of their contents for easier versioning • Revises the file names of your assets so that you can use heavy caching • Updates your HTML to reference these new hyper-optimized CSS + JS files Thursday, 13 December 12
  • 60.
    • May rerunthe build script on file changes (grunt's watch task ❤) • May automatically reload the page in your browsers whenever watched files change, through some socket.io magic. Thursday, 13 December 12
  • 61.
    node-build-script + bower + more opinions = Thursday, 13 December 12
  • 62.
  • 63.
    By Paul Irish,Addy Osmani, Sindre Sorhus, Mickael Daniel, Eric Bidelman, and the Yeoman Community. Thursday, 13 December 12
  • 64.
    • HTML5 Boilerplate • Twitter Bootstrap • Twitter Bootstrap plugins • RequireJS • Support for ES6 Modules • Wraps bower Thursday, 13 December 12
  • 65.
    Lightning-fast scaffolding — Easily scaffold new projects with customizable templates (e.g HTML5 Boilerplate, Twitter Bootstrap), AMD (via RequireJS) and more. • Automatically compile CoffeeScript & Compass — Our LiveReload watch process automatically compiles source files and refreshes your browser whenever a change is made so you don't have to. Thursday, 13 December 12
  • 66.
    Automatically lint your scripts — All your scripts are automatically run against jshint to ensure they're following language best- practices. • Built-in preview server — No more having to fire up your own HTTP Server. My built- in one can be fired with just one command. • Awesome Image Optimization — I optimize all your images using OptiPNG and JPEGTran so your users can spend less time Thursday, 13 December 12
  • 67.
    • Integrated packagemanagement — Need a dependency? It's just a keystroke away. I allow you to easily search for new packages via the command-line (e.g., yeoman search jquery), install them and keep them updated without needing to open your browser. • Support for ES6 module syntax — Experiment with writing modules using the latest ECMAScript 6 module syntax. This is an experimental feature that transpiles back to ES5 so you can use the code in all Thursday, 13 December 12
  • 68.
    PhantomJS Unit Testing — Easily run your unit tests in headless WebKit via PhantomJS. When you create a new application, I also include some test scaffolding for your app. Thursday, 13 December 12