Dethroning Grunt: Simple and Effective Builds with gulp.js

50 %
50 %
Information about Dethroning Grunt: Simple and Effective Builds with gulp.js
Technology

Published on March 10, 2014

Author: jayharris

Source: slideshare.net

Description

Grunt is king. It is the ubiquitous task runner used for most nodejs projects and has quickly expanded to conquer other software ecosystems. However, its kingdom is vulnerable. Grunt does not align well with many nodejs paradigms and is notorious for its harsh learning curve. Meet Gulp, the challenger in the taskrunner revolution. Gulp’s easy configuration produces an easy learning curve, and its alignment with nodejs paradigms eliminates the friction. Grab your ticket, your foam finger, and your team-colored face paint and witness the battle, the revolution, and the crowning of Gulp.

@jayharris #dethroningGrunt SIMPLE AND EFFECTIVE BUILDS W I T H G U L P. J S

what is a taskrunner?

that is a lot of things to do task runners simplify to one command

 grunt  gulp

focusing on five tasks

demo code  queenseight.com  aranasoft/queenseight

//  Project  Specific  Tasks grunt.loadNpmTasks('grunt-­‐bower-­‐task'); grunt.loadNpmTasks('grunt-­‐coffeelint'); grunt.loadNpmTasks('grunt-­‐contrib-­‐clean'); grunt.loadNpmTasks('grunt-­‐contrib-­‐coffee'); grunt.loadNpmTasks('grunt-­‐contrib-­‐concat'); grunt.loadNpmTasks('grunt-­‐contrib-­‐connect'); grunt.loadNpmTasks('grunt-­‐contrib-­‐copy'); grunt.loadNpmTasks('grunt-­‐contrib-­‐cssmin'); grunt.loadNpmTasks('grunt-­‐contrib-­‐jade'); grunt.loadNpmTasks('grunt-­‐contrib-­‐jshint'); grunt.loadNpmTasks('grunt-­‐contrib-­‐less'); grunt.loadNpmTasks('grunt-­‐contrib-­‐uglify'); grunt.loadNpmTasks('grunt-­‐contrib-­‐watch');

//  General-­‐Purpose  Tasks grunt.loadNpmTasks('grunt-­‐bower-­‐task'); grunt.loadNpmTasks('grunt-­‐coffeelint'); grunt.loadNpmTasks('grunt-­‐contrib-­‐clean'); grunt.loadNpmTasks('grunt-­‐contrib-­‐coffee'); grunt.loadNpmTasks('grunt-­‐contrib-­‐concat'); grunt.loadNpmTasks('grunt-­‐contrib-­‐connect'); grunt.loadNpmTasks('grunt-­‐contrib-­‐copy'); grunt.loadNpmTasks('grunt-­‐contrib-­‐cssmin'); grunt.loadNpmTasks('grunt-­‐contrib-­‐jade'); grunt.loadNpmTasks('grunt-­‐contrib-­‐jshint'); grunt.loadNpmTasks('grunt-­‐contrib-­‐less'); grunt.loadNpmTasks('grunt-­‐contrib-­‐uglify'); grunt.loadNpmTasks('grunt-­‐contrib-­‐watch');

//  13  tasks  in  all grunt.loadNpmTasks('grunt-­‐bower-­‐task'); grunt.loadNpmTasks('grunt-­‐coffeelint'); grunt.loadNpmTasks('grunt-­‐contrib-­‐clean'); grunt.loadNpmTasks('grunt-­‐contrib-­‐coffee'); grunt.loadNpmTasks('grunt-­‐contrib-­‐concat'); grunt.loadNpmTasks('grunt-­‐contrib-­‐connect'); grunt.loadNpmTasks('grunt-­‐contrib-­‐copy'); grunt.loadNpmTasks('grunt-­‐contrib-­‐cssmin'); grunt.loadNpmTasks('grunt-­‐contrib-­‐jade'); grunt.loadNpmTasks('grunt-­‐contrib-­‐jshint'); grunt.loadNpmTasks('grunt-­‐contrib-­‐less'); grunt.loadNpmTasks('grunt-­‐contrib-­‐uglify'); grunt.loadNpmTasks('grunt-­‐contrib-­‐watch');

gruntfile.coffee timer  =  require  "grunt-­‐timer" fs  =  require  'fs' path  =  require  'path' server  =  require  './config/server' urlrouter  =  require  'urlrouter' module.exports  =  (grunt)  -­‐>    timer.init  grunt    #  Project  configuration.    grunt.initConfig        pkg:  grunt.file.readJSON  'package.json'        files:            coffee:                app:  "app/js/**/*.coffee"                generated:  "generated/js/app.coffee.js"                css:                vendor:  "vendor/css/**/*.css"                app:  "app/css/**/*.css"                concatenated:  "generated/css/app.css"                minified:  "dist/css/app.css"                minifiedWebRelative:  "css/app.css"                            img:                root:  "img"            jade:                pages:  "**/*.jade"                pageRoot:  "app/pages/"            js:                app:  "app/js/**/*.js"                vendor:  [                    "vendor/components/jquery/jquery.js"                    "vendor/components/underscore/underscore.js"                    "vendor/components/angular/angular.js"                    "vendor/js/**/*.js"                ]                concatenatedVendor:  "generated/js/vendor.js"                minifiedVendor:  "dist/js/vendor.js"                minifiedVendorWebRelative:  "js/vendor.js"                concatenated:  "generated/js/app.js"                minified:  "dist/js/app.js"                minifiedWebRelative:  "js/app.js"                                            less:                app:  "app/css/app.less"                vendor:  "vendor/css/**/*.less"                generatedApp:  "generated/css/app.less.css"                generatedVendor:  "generated/css/vendor.less.css"                watch:  "app/css/**/*.less"            webfonts:                root:  "fonts"        bower:            install:                options:                    copy:  false        coffee:            compile:                files:                    "<%=  files.coffee.generated  %>":  "<%=  files.coffee.app  %>"                            coffeelint:            app:  [                "<%=  files.coffee.app  %>"            ]        concat:            css:                src:  [                    "<%=  files.less.generatedVendor  %>"                    "<%=  files.css.vendor  %>"                    "<%=  files.less.generatedApp  %>"                    "<%=  files.css.app  %>"                ]                dest:  "<%=  files.css.concatenated  %>"            js:                src:  [                    "<%=  files.coffee.generated  %>"                    "<%=  files.js.app  %>"                ]                dest:  "<%=  files.js.concatenated  %>"            jsVendor:                src:  ["<%=  files.js.vendor  %>"]                dest:  "<%=  files.js.concatenatedVendor  %>"        connect:            server:                options:                    port:  8000                    base:  'generated'                    open:  true                    middleware:  (connect,  options)  -­‐>                        middlewares  =  [];                        if  (!Array.isArray(options.base))                            options.base  =  [options.base]                                                directory  =  options.directory  ||  options.base[options.base.length  -­‐  1]                        options.base.forEach  (base)  -­‐>                            #  Serve  static  files.                            middlewares.push(connect.static(base))                        middlewares.push  urlrouter(server.drawRoutes)                        #  Make  directory  browse-­‐able.                        middlewares.push  connect.directory(directory)                        middlewares        copy:            imagesDev:                files:  [{                    expand:  true                    cwd:  "app/img/"                    src:  "**"                    dest:  "generated/<%=  files.img.root  %>/"                }                {                    expand:  true                    cwd:  "vendor/img/"                    src:  "**"                    dest:  "generated/<%=  files.img.root  %>/"                }]            imagesDist:                files:  [{                    expand:  true                    cwd:  "app/img/"                    src:  "**"                    dest:  "dist/<%=  files.img.root  %>/"                }                {                    expand:  true                    cwd:  "vendor/img/"                    src:  "**"                    dest:  "dist/<%=  files.img.root  %>/"                }]            staticDev:                files:  [                    expand:  true                    cwd:  "app/static"                    src:  "**"                    dest:  'generated'                ]            staticDist:                files:  [                    expand:  true                    cwd:  "app/static"                    src:  "**"                    dest:  'dist'                ]            webfontsDev:                files:  [{                    expand:  true                    cwd:  "vendor/webfonts/"                    src:  "**"                    dest:  "generated/<%=  files.webfonts.root  %>/"                }                {                    expand:  true                    cwd:  "vendor/components/font-­‐awesome/fonts/"                    src:  "**"                    dest:  "generated/<%=  files.webfonts.root  %>/"                }]            webfontsDist:                files:  [{                    expand:  true                    cwd:  "vendor/webfonts/"                    src:  "**"                    dest:  "dist/<%=  files.webfonts.root  %>/"                }                {                    expand:  true                    cwd:  "vendor/components/font-­‐awesome/fonts/"                    src:  "**"                    dest:  "dist/<%=  files.webfonts.root  %>/"                }]                        cssmin:            compress:                files:                    "<%=  files.css.minified  %>":  "<%=  files.css.concatenated  %>"            css:                files:  ["<%=  files.css.vendor  %>",  "<%=  files.css.app  %>"]                tasks:  ["concat:css"]        jade:            dev:                options:                    pretty:  true                    data:                        js:  "<%=  files.js.minifiedWebRelative  %>"                          jsVendor:  "<%=  files.js.minifiedVendorWebRelative  %>"                        css:  "<%=  files.css.minifiedWebRelative  %>"                        pkg:  "<%=  pkg  %>"                files:  [{                    expand:  true                    src:  "<%=  files.jade.pages  %>"                    cwd:  "<%=  files.jade.pageRoot  %>"                    dest:  "generated/"                    ext:  ".html"                }]            dist:                options:                    data:                        js:  "<%=  minifiedWebRelative  %>"                        jsVendor:  "<%=  minifiedVendorWebRelative  %>"                        css:  "<%=  files.css.minifiedWebRelative  %>"                        pkg:  "<%=  pkg  %>"                files:  [{                    expand:  true                    src:  "<%=  files.jade.pages  %>"                    cwd:  "<%=  files.jade.pageRoot  %>"                    dest:  "dist/"                    ext:  ".html"                }]            js:                files:  ["<%=  files.js.vendor  %>",  "<%=  files.js.app  %>"]                tasks:  ["concat:js"]        jshint:            files:  ["<%=  files.js.app  %>"]            options:            #  enforcing  options                curly:  true                eqeqeq:  true                latedef:  true                newcap:  true                noarg:  true            #  relaxing  options                boss:  true                eqnull:  true                sub:  true            #  environment/globals                browser:  true                        less:            options:                paths:  ["app/css",  "vendor/css"]            compile:                files:                    "<%=  files.less.generatedVendor  %>":  "<%=  files.less.vendor  %>"                    "<%=  files.less.generatedApp  %>":  "<%=  files.less.app  %>"                            uglify:            options:                banner:  '/*!  <%=  pkg.name  %>  <%=  grunt.template.today("yyyy-­‐mm-­‐dd")  %>  */n'            js:                files:                    "<%=  files.js.minified  %>":  "<%=  files.js.concatenated  %>"            jsVendor:                files:                    "<%=  files.js.minifiedVendor  %>":  "<%=  files.js.concatenatedVendor  %>"        clean:            bower:                src:  bowerDirectory  grunt            js:                src:  "<%=  files.js.concatenated  %>"            css:                src:  "<%=  files.css.concatenated  %>"            dist:                src:  ["dist",  "generated"]        watch:            coffee:                files:  "<%=  files.coffee.app  %>"                tasks:  ["coffeelint",  "coffee",  "concat:js"]            images:                files:  ["app/img/**/*.*",  "vendor/img/**/*.*"]                tasks:  ["copy:imagesDev"]                            jade:                files:  ["<%=  files.jade.pageRoot  %>/<%=  files.jade.pages  %>"]                tasks:  ["jade:dev"]            less:                files:  [                    "<%=  files.less.vendor  %>"                    "<%=  files.less.watch  %>"                ]                tasks:  ["less",  "concat:css"]                lint:                files:  "<%=  files.js.app  %>"                tasks:  ["jshint"]                webfonts:                files:  ["vendor/webfonts/**/*.*",  "vendor/components/font-­‐awesome/fonts/**/*.*"]                tasks:  ["copy:webfontsDev"]                            livereload:                options:                    livereload:  true                files:  "dist/**/*.*"                    grunt.loadNpmTasks  'grunt-­‐bower-­‐task'    grunt.loadNpmTasks  'grunt-­‐coffeelint'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐clean'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐coffee'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐concat'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐connect'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐copy'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐cssmin'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐jshint'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐less'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐jade'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐uglify'    grunt.loadNpmTasks  'grunt-­‐contrib-­‐watch'    grunt.registerTask  'default',  [        'common'        'dev'    ]    grunt.registerTask  'common',  [        'bower'        'coffeelint'        'jshint'        'coffee'        'less'        'concat'        'copy:staticDev'        'copy:imagesDev'        'copy:webfontsDev'        'jade:dev'    ]    grunt.registerTask  'dev',  [        'connect'        'watch'    ]    grunt.registerTask  'dist',  [        'uglify'        'cssmin'        'copy:staticDist'        'copy:imagesDist'        'copy:webfontsDist'        'jade:dist'    ] bowerDirectory  =  (grunt)  -­‐>    bowerrc  =  path.join(process.cwd(),  ".bowerrc")    bowerConfig  =  grunt.file.readJSON(bowerrc)  unless  !fs.existsSync(bowerrc)    bowerConfig?.directory  ||  "vendor/components"

├──  css │      ├──  app.less │      ├──  mixins.less │      └──  variables.less ├──  img │      ├──  arana-­‐software.png │      ├──  arana-­‐software@2x.png │      ├──  banner-­‐lg.png │      ├──  banner-­‐md.png │      ├──  banner-­‐sm.png │      ├──  crown.png │      ├──  leather@1x.jpg │      ├──  leather@2x.jpg │      └──  wood.png ├──  js │      ├──  app.coffee │      ├──  controllers │      │      └──  board.coffee │      ├──  directives │      │      └──  board.js │      └──  templates │              └──  board.coffee ├──  pages │      └──  index.jade └──  static        └──  favicon.ico gruntfile.coffee timer  =  require  "grunt-­‐timer" fs  =  require  'fs' path  =  require  'path' server  =  require  './config/server' urlrouter  =  require  'urlrouter'            jsVendor:                src:  ["<%=  files.js.vendor  %>"]                dest:  "<%=  files.js.concatenatedVendor  %>"                {            css:                    expand:  true                files:  ["<%=  files.css.vendor  %>",  "<%=  files.css.app  %>"]                    cwd:  "vendor/components/font-­‐awesome/fonts/"                tasks:  ["concat:css"]                    src:  "**"                    dest:  "dist/<%=  files.webfonts.root  %>/"            images:                }]                files:  ["app/img/**/*.*",  "vendor/img/**/*.*"]                                tasks:  ["copy:imagesDev"]        cssmin:                            compress:            jade:                files:                files:  ["<%=  files.jade.pageRoot  %>/<%=  files.jade.pages  %>"]                    "<%=  files.css.minified  %>":  "<%=  files.css.concatenated  %>"                tasks:  ["jade:dev"]        connect:            server: module.exports  =  (grunt)  -­‐>                options:    timer.init  grunt                    port:  8000                    base:  'generated'    #  Project  configuration.                    open:  true    grunt.initConfig                    middleware:  (connect,  options)  -­‐>        pkg:  grunt.file.readJSON  'package.json'                        middlewares  =  [];                        if  (!Array.isArray(options.base))        jade:            js:        files:                            options.base  =  [options.base]            dev:                files:  ["<%=  files.js.vendor  %>",  "<%=  files.js.app  %>"]            coffee:                                        options:                tasks:  ["concat:js"]                app:  "app/js/**/*.coffee"                        directory  =  options.directory  ||  options.base[options.base.length  -­‐  1]                    pretty:  true                generated:  "generated/js/app.coffee.js"                        options.base.forEach  (base)  -­‐>                    data:            less:                                #  Serve  static  files.                        js:  "<%=  files.js.minifiedWebRelative  %>"                  files:  [            css:                            middlewares.push(connect.static(base))                        jsVendor:  "<%=  files.js.minifiedVendorWebRelative  %>"                    "<%=  files.less.vendor  %>"                vendor:  "vendor/css/**/*.css"                        css:  "<%=  files.css.minifiedWebRelative  %>"                    "<%=  files.less.watch  %>"                app:  "app/css/**/*.css"                        middlewares.push  urlrouter(server.drawRoutes)                        pkg:  "<%=  pkg  %>"                ]                concatenated:  "generated/css/app.css"                        #  Make  directory  browse-­‐able.                files:  [{                tasks:  ["less",  "concat:css"]                minified:  "dist/css/app.css"                        middlewares.push  connect.directory(directory)                    expand:  true                    minifiedWebRelative:  "css/app.css"                        middlewares                    src:  "<%=  files.jade.pages  %>"            lint:                                    cwd:  "<%=  files.jade.pageRoot  %>"                files:  "<%=  files.js.app  %>"            img:        copy:                    dest:  "generated/"                tasks:  ["jshint"]                root:  "img"            imagesDev:                    ext:  ".html"                    files:  [{                }]            webfonts:            jade:                    expand:  true            dist:                files:  ["vendor/webfonts/**/*.*",  "vendor/components/font-­‐awes                pages:  "**/*.jade"                    cwd:  "app/img/"                options:                tasks:  ["copy:webfontsDev"]                pageRoot:  "app/pages/"                    src:  "**"                    data:                                    dest:  "generated/<%=  files.img.root  %>/"                        js:  "<%=  minifiedWebRelative  %>"            livereload:            js:                }                        jsVendor:  "<%=  minifiedVendorWebRelative  %>"                options:                app:  "app/js/**/*.js"                {                        css:  "<%=  files.css.minifiedWebRelative  %>"                    livereload:  true                vendor:  [                    expand:  true                        pkg:  "<%=  pkg  %>"                files:  "dist/**/*.*"                    "vendor/components/jquery/jquery.js"                    cwd:  "vendor/img/"                files:  [{                                    "vendor/components/underscore/underscore.js"                    src:  "**"                    expand:  true    grunt.loadNpmTasks  'grunt-­‐bower-­‐task'                    "vendor/components/angular/angular.js"                    dest:  "generated/<%=  files.img.root  %>/"                    src:  "<%=  files.jade.pages  %>"    grunt.loadNpmTasks  'grunt-­‐coffeelint'                    "vendor/js/**/*.js"                }]                    cwd:  "<%=  files.jade.pageRoot  %>"    grunt.loadNpmTasks  'grunt-­‐contrib-­‐clean'                ]            imagesDist:                    dest:  "dist/"    grunt.loadNpmTasks  'grunt-­‐contrib-­‐coffee'                concatenatedVendor:  "generated/js/vendor.js"                files:  [{                    ext:  ".html"    grunt.loadNpmTasks  'grunt-­‐contrib-­‐concat'                minifiedVendor:  "dist/js/vendor.js"                    expand:  true                }]    grunt.loadNpmTasks  'grunt-­‐contrib-­‐connect'                minifiedVendorWebRelative:  "js/vendor.js"                    cwd:  "app/img/"    grunt.loadNpmTasks  'grunt-­‐contrib-­‐copy'                concatenated:  "generated/js/app.js"                    src:  "**"        jshint:    grunt.loadNpmTasks  'grunt-­‐contrib-­‐cssmin'                minified:  "dist/js/app.js"                    dest:  "dist/<%=  files.img.root  %>/"            files:  ["<%=  files.js.app  %>"]    grunt.loadNpmTasks  'grunt-­‐contrib-­‐jshint'                minifiedWebRelative:  "js/app.js"                                }            options:    grunt.loadNpmTasks  'grunt-­‐contrib-­‐less'                                {            #  enforcing  options    grunt.loadNpmTasks  'grunt-­‐contrib-­‐jade'            less:                    expand:  true                curly:  true    grunt.loadNpmTasks  'grunt-­‐contrib-­‐uglify'                app:  "app/css/app.less"                    cwd:  "vendor/img/"                eqeqeq:  true    grunt.loadNpmTasks  'grunt-­‐contrib-­‐watch'                vendor:  "vendor/css/**/*.less"                    src:  "**"                latedef:  true                generatedApp:  "generated/css/app.less.css"                    dest:  "dist/<%=  files.img.root  %>/"                newcap:  true    grunt.registerTask  'default',  [                generatedVendor:  "generated/css/vendor.less.css"                }]                noarg:  true        'common'                watch:  "app/css/**/*.less"            staticDev:            #  relaxing  options        'dev'                files:  [                boss:  true    ]            webfonts:                    expand:  true                eqnull:  true    grunt.registerTask  'common',  [                root:  "fonts"                    cwd:  "app/static"                sub:  true        'bower'                    src:  "**"            #  environment/globals        'coffeelint'        bower:                    dest:  'generated'                browser:  true        'jshint'            install:                ]                        'coffee'                options:            staticDist:        less:        'less'                    copy:  false                files:  [            options:        'concat'                    expand:  true                paths:  ["app/css",  "vendor/css"]        'copy:staticDev'        coffee:                    cwd:  "app/static"            compile:        'copy:imagesDev'            compile:                    src:  "**"                files:        'copy:webfontsDev'                files:                    dest:  'dist'                    "<%=  files.less.generatedVendor  %>":  "<%=  files.less.vendor  %>"        'jade:dev'                    "<%=  files.coffee.generated  %>":  "<%=  files.coffee.app  %>"                ]                    "<%=  files.less.generatedApp  %>":  "<%=  files.less.app  %>"    ]                                webfontsDev:                        grunt.registerTask  'dev',  [        coffeelint:                files:  [{        uglify:        'connect'            app:  [                    expand:  true            options:        'watch'                "<%=  files.coffee.app  %>"                    cwd:  "vendor/webfonts/"                banner:  '/*!  <%=  pkg.name  %>  <%=  grunt.template.today("yyyy-­‐mm-­‐dd")  %>  */n'    ]            ]                    src:  "**"            js:    grunt.registerTask  'dist',  [                    dest:  "generated/<%=  files.webfonts.root  %>/"                files:        'uglify'        concat:                }                    "<%=  files.js.minified  %>":  "<%=  files.js.concatenated  %>"        'cssmin'            css:                {            jsVendor:        'copy:staticDist'                src:  [                    expand:  true                files:        'copy:imagesDist'                    "<%=  files.less.generatedVendor  %>"                    cwd:  "vendor/components/font-­‐awesome/fonts/"                    "<%=  files.js.minifiedVendor  %>":  "<%=  files.js.concatenatedVendor  %>"        'copy:webfontsDist'                    "<%=  files.css.vendor  %>"                    src:  "**"        'jade:dist'                    "<%=  files.less.generatedApp  %>"                    dest:  "generated/<%=  files.webfonts.root  %>/"        clean:    ]                    "<%=  files.css.app  %>"                }]            bower:                ]                src:  bowerDirectory  grunt bowerDirectory  =  (grunt)  -­‐>                dest:  "<%=  files.css.concatenated  %>"            webfontsDist:            js:    bowerrc  =  path.join(process.cwd(),  ".bowerrc")                files:  [{                src:  "<%=  files.js.concatenated  %>"    bowerConfig  =  grunt.file.readJSON(bowerrc)  unless  !fs.existsSync(bow                    expand:  true    bowerConfig?.directory  ||  "vendor/components"            js:                    cwd:  "vendor/webfonts/"            css:                src:  [                    src:  "**"                src:  "<%=  files.css.concatenated  %>"                    "<%=  files.coffee.generated  %>"                    dest:  "dist/<%=  files.webfonts.root  %>/"                    "<%=  files.js.app  %>"                }            dist:                ]                src:  ["dist",  "generated"]                dest:  "<%=  files.js.concatenated  %>"        watch:            coffee:                files:  "<%=  files.coffee.app  %>"                tasks:  ["coffeelint",  "coffee",  "concat:js"]

'use  strict'; var  util  =  require('util'); var  Orchestrator  =  require('orchestrator'); var  gutil  =  require('gulp-­‐util'); var  deprecated  =  require('deprecated'); var  vfs  =  require('vinyl-­‐fs'); function  Gulp(){    Orchestrator.call(this); } util.inherits(Gulp,  Orchestrator); Gulp.prototype.task  =  Gulp.prototype.add; Gulp.prototype.run  =  function(){    //  run()  is  deprecated  as  of  3.5  and  will  be  removed  in  4.0    //  use  task  dependencies  instead    //  impose  our  opinion  of  "default"  tasks  onto  orchestrator    var  tasks  =  arguments.length  ?  arguments  :  ['default'];    this.start.apply(this,  tasks); }; Gulp.prototype.src  =  vfs.src; Gulp.prototype.dest  =  vfs.dest; Gulp.prototype.watch  =  function  (glob,  opt,  fn)  {    if  (!fn)  {        fn  =  opt;        opt  =  null;    }    //  array  of  tasks  given    if  (Array.isArray(fn))  {        return  vfs.watch(glob,  opt,  function(){            this.start.apply(this,  fn);        }.bind(this));    }    return  vfs.watch(glob,  opt,  fn); }; //  let  people  use  this  class  from  our  instance Gulp.prototype.Gulp  =  Gulp; //  deprecations deprecated.field('gulp.env  has  been  deprecated.  Use  gulp-­‐util.env  or  your  own  CLI  parser  instead.',  console.log,   Gulp.prototype,  'env',  gutil.env); Gulp.prototype.run  =  deprecated.method('gulp.run()  has  been  deprecated.  Use  task  dependencies  or  gulp.watch  task   triggering  instead.',  console.log,  Gulp.prototype.run); var  inst  =  new  Gulp(); module.exports  =  inst;

.src(globs[, options])

.dest(path)

.task(name[, deps], fn)

.watch(glob [, options], tasks)

.pipe(destination)

 level up grok streams

   a task: read, concatenate, write

    additional steps add overhead

    extraneous disk I/O

      extraneous configuration

    streams pipe from task to task

    additional steps without overhead

 level up the first gulp

 npm install -g gulp npm install -D gulp touch gulpfile.js

//gulpfile.js var  gulp      =  require('gulp'); var  coffee  =  require('gulp-­‐coffee'); var  concat  =  require('gulp-­‐concat'); var  uglify  =  require('gulp-­‐uglify');

gulp.src('app/js/**/*.coffee') 

gulp.src('app/js/**/*.coffee')        .pipe(gulp.dest('dist/js')); 

gulp.src('app/js/**/*.coffee')        .pipe(coffee()) .pipe(concat('app.js')) .pipe(uglify()) .pipe(gulp.dest('dist/js'));    

gulp.src('app/js/**/*.coffee')        .pipe(coffee()) .pipe(concat('app.js')) .pipe(gulp.dest('test/js')) .pipe(uglify()) .pipe(gulp.dest('dist/js'));    

gulp.task('coffee',  function()  {    gulp.src('app/js/**/*.coffee')            .pipe(coffee())    .pipe(concat('app.js'))    .pipe(gulp.dest('test/js'))    .pipe(uglify())    .pipe(gulp.dest('dist/js')); });

gulp.task('watch',  function()  { gulp.watch('app/js/**/*.coffee',                      ['coffee']); }); 

gulp.task('default',          ['coffee','watch']);     

 level up dependencies

gulp.task('css',                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); });  

var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    bower(); }); 

gulp.task('css',  ['install'],                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); });   

var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    bower(); }); //  Doesn't  work  as  expected 

our five tasks

┌ │ ┤ │ └ ┬ │ └ ─ expected dependency tree

┌ │ ├ │ ┼ │ ├ │ └ actual tree

gulp.task('stuff',  function()  {    doStuff();    });

//  Option  1:  Callback gulp.task('stuff',  function(done)  {    doSyncStuff()    done(err); });

var  Q  =  require('q'); //  Option  2:  Promise gulp.task('stuff',  function()  {    var  deferred  =  Q.defer();    doAsyncStuff(deferred.resolve);    return  deferred.promise; });

//  Option  3:  Return  stream gulp.task('stuff',  function()  {    var  stream  =  doStreamStuff();    return  stream; });

gulp.task  'stuff',  ()  -­‐>    doStreamStuff()

#  Get  return  stream  for  free! gulp.task  'stuff',  ()  -­‐>    doStreamStuff() gulp.task('stuff',  function()  {    return  doStreamStuff();    });

var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    bower(); }); 

var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    return  bower();  //  Win! }); 

//  Back  to  where  we  were gulp.task('css',                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); });  

gulp.task('css',  ['install'],                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); }); 

 level up using coffee

//gulpfile.js gulp.task('css',  ['install'],                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); }); 

#  gulpfile.coffee gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  'app/css/app.less'            .pipe  less()    .pipe  cssmin()      .pipe  gulp.dest('dist/css') 

 gulp --require coffee-script/register

 more gulpfile.js //gulpfile.js require('coffee-­‐script'); require('./gulpfile.coffee');  gulp

 level up merging streams

   

     

gulp.task  'js',  ()  -­‐>    gulp.src  files.coffee            .pipe  coffee()            .pipe  concat('app.js')            .pipe  uglify()            .pipe  gulp.dest('dist/js')    

evtstream  =  require  'event-­‐stream'      #  and/or streamq      =  require  'streamqueue'

gulp.task  'js',  ()  -­‐>    gulp.src(files.coffee)            .pipe(coffee())            .pipe  concat('app.js')            .pipe  uglify()            .pipe  gulp.dest('dist/js')    

gulp.task  'js',  ()  -­‐>    evtstream.concat(        gulp.src(files.coffee)                .pipe(coffee()),        gulp.src(files.js))            .pipe  concat('app.js')            .pipe  uglify()            .pipe  gulp.dest('dist/js')     

gulp.task  'js',  ()  -­‐>    es.concat(        gulp.src(files.coffee)                .pipe(coffee()),        gulp.src(files.js))            .pipe  concat('app.js')            .pipe  uglify()            .pipe  gulp.dest('dist/js')     

gulp.task  'js',  ()  -­‐>    sq  =  streamq  {objectmode:true}    sq.queue  gulp.src(files.coffee)                              .pipe(coffee()    sq.queue  gulp.src(files.js)    sq.done().pipe  concat('app.js')                      .pipe  uglify()                      .pipe  gulp.dest('dist/js')     

 level up error handling

gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  less()      .pipe  cssmin()    .pipe  gulp.dest('dist/css') 

//  app.less .mayhem  {    font-­‐weight:  bold;    color:              @red; } }  //  too  many  '{'  ===  BOOM! 

[gulp]  Running  'css'... events.js:72                throw  er;  //  Unhandled  'error'                            ^ Error:  missing  opening  `{`  in  file  ./c  

gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  less()      .pipe  cssmin()    .pipe  gulp.dest('dist/css') 

gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  less().on('error',(err)-­‐>                console.log(''+err)  if  err            )  #  Ick.    .pipe  cssmin()    .pipe  gulp.dest('dist/css') 

plumber  =  require  'gulp-­‐plumber' gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  plumber()  #Win!            .pipe  less()      .pipe  cssmin()    .pipe  gulp.dest('dist/css') 

[gulp]  Running  'css'... [gulp]  Error  in  plugin  'gulp-­‐less':    missing  opening  `{`  in  file  app.less [gulp]  Finished  'css'  in  21  ms 

 level up master class

gutil  =  require  'gulp-­‐util' 

gulp.src  'app/css/*.css'    .pipe  concat('app.css')    .pipe(if  gutil.env.dest  ==  'prod'                then  cssmin()                else  gutil.noop())    .pipe  gulp.dest('dist/css')      

gulp.src  'app/css/*.css'    .pipe  concat('app.css')    .pipe(if  gutil.env.dest  ==  'prod'                then  cssmin()                else  gutil.noop())    .pipe  gulp.dest('dist/css')      

 gulp  -­‐-­‐port=8000  -­‐-­‐dest=prod gutil.env.port  ===  8000 gutil.env.dest  ===  'prod' 

  echo  Total  Files:  $(      find  .  -­‐type  f  -­‐print  |  wc  -­‐l) Total  Files:  1000  echo  watch  will  vomit

 level up comparison

gruntfile.coffee timer  =  require  "grunt-­‐timer" fs  =  require  'fs' path  =  require  'path' server  =  require  './config/server' urlrouter  =  require  'urlrouter' module.exports  =  (grunt)  -­‐>    timer.init  grunt    #  Project  configuration.    grunt.initConfig        pkg:  grunt.file.readJSON  'package.json'        files:            coffee:                app:  "app/js/**/*.coffee"                generated:  "generated/js/app.coffee.js"                css:                vendor:  "vendor/css/**/*.css"                app:  "app/css/**/*.css"                concatenated:  "generated/css/app.css"                minified:  "dist/css/app.css"                minifiedWebRelative:  "css/app.css"                            img:                root:  "img"            jade:                pages:  "**/*.jade"                pageRoot:  "app/pages/"            js:                app:  "app/js/**/*.js"                vendor:  [                    "vendor/components/jquery/jquery.js"                    "vendor/components/underscore/underscore.js"                    "vendor/components/angular/angular.js"                    "vendor/js/**/*.js"                ]                concatenatedVendor:  "generated/js/vendor.js"                minifiedVendor:  "dist/js/vendor.js"                minifiedVendorWebRelative:  "js/vendor.js"                concatenated:  "generated/js/app.js"                minified:  "dist/js/app.js"                minifiedWebRelative:  "js/app.js"                                            less:                app:  "app/css/app.less"                vendor:  "vendor/css/**/*.less"                generatedApp:  "generated/css/app.less.css"                generatedVendor:  "generated/css/vendor.less.css"                watch:  "app/css/**/*.less"            webfonts:                root:  "fonts"        bower:            install:                options:                    copy:  false        coffee:            compile:                files:                    "<%=  files.coffee.generated  %>":  "<%=  files.coffee.app  %>"                            coffeelint:            app:  [                "<%=  files.coffee.app  %>"            ]        concat:            css:                src:  [                    "<%=  files.less.generatedVendor  %>"                    "<%=  files.css.vendor  %>"                    "<%=  files.less.generatedApp  %>"                    "<%=  files.css.app  %>"                ]                dest:  "<%=  files.css.concatenated  %>"            js:                src:  [                    "<%=  files.coffee.generated  %>"                    "<%=  files.js.app  %>"                ]                dest:  "<%=  files.js.concatenated  %>"            jsVendor:                src:  ["<%=  files.js.vendor  %>"]                dest:  "<%=  files.js.concatenatedVendor  %>"        connect:            server:                options:                    port:  8000                    base:  'generated'  

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

Dethroning Grunt: Simple and Effective Builds with gulp.js ...

Grunt is king. It is the ubiquitous task runner used for most nodejs projects and has quickly expanded to conquer other software ecosystems. However, its ...
Read more

Presentations by Jay Harris // Speaker Deck

Dethroning Grunt: Simple and Effective Builds with gulp.js. Feb 10, 2014 by Jay Harris. ... Building Effective Presentations.
Read more

Arana Software - Google+

... Arana Software provides web application ... Dethroning Grunt: Simple and Effective Builds with ... Simple and Effective Builds with gulp.js. 1.
Read more

gulp.js - the streaming build system

gulp.js. Docs Plugins Twitter ... By preferring code over configuration, gulp keeps things simple and makes complex tasks ... your build works exactly as ...
Read more

Grunt | LinkedIn

Grunt receives a... , right? Build systems seem to ... Your new friend is Grunt. Grunt is a super simple, ... Dethroning Grunt: Simple and Effective Builds ...
Read more

Grunt vs Gulp - Beyond the Numbers — Jack Hsu

Grunt vs Gulp - Beyond the ... One of the pain points I’ve experienced with Grunt is the over-configuration of simple ... Speedtesting gulp.js and Grunt;
Read more

Grunt: The JavaScript Task Runner

While installing grunt is simple, it's slightly more involved to get it running on your project. ... grunt Running "jshint:gruntfile" (jshint) ...
Read more

Talks - CBusJS

Grunt, Gulp, Broccoli, ... Gulp.js. January 21, ... Dethroning Grunt: Simple and Effective Builds with Gulp. July 16, ...
Read more