Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Dethroning Grunt: Simple and Effective Builds with gulp.js

2,502 views

Published on

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.

Published in: Technology
  • Be the first to comment

Dethroning Grunt: Simple and Effective Builds with gulp.js

  1. 1. @jayharris #dethroningGrunt SIMPLE AND EFFECTIVE BUILDS W I T H G U L P. J S
  2. 2. what is a taskrunner?
  3. 3. that is a lot of things to do task runners simplify to one command
  4. 4.  grunt  gulp
  5. 5. focusing on five tasks
  6. 6. demo code  queenseight.com  aranasoft/queenseight
  7. 7. //  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');
  8. 8. //  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');
  9. 9. //  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');
  10. 10. 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"
  11. 11. ├──  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"]
  12. 12. '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;
  13. 13. .src(globs[, options])
  14. 14. .dest(path)
  15. 15. .task(name[, deps], fn)
  16. 16. .watch(glob [, options], tasks)
  17. 17. .pipe(destination)
  18. 18.  level up grok streams
  19. 19.    a task: read, concatenate, write
  20. 20.     additional steps add overhead
  21. 21.     extraneous disk I/O
  22. 22.       extraneous configuration
  23. 23.     streams pipe from task to task
  24. 24.     additional steps without overhead
  25. 25.  level up the first gulp
  26. 26.  npm install -g gulp npm install -D gulp touch gulpfile.js
  27. 27. //gulpfile.js var  gulp      =  require('gulp'); var  coffee  =  require('gulp-­‐coffee'); var  concat  =  require('gulp-­‐concat'); var  uglify  =  require('gulp-­‐uglify');
  28. 28. gulp.src('app/js/**/*.coffee') 
  29. 29. gulp.src('app/js/**/*.coffee')        .pipe(gulp.dest('dist/js')); 
  30. 30. gulp.src('app/js/**/*.coffee')        .pipe(coffee()) .pipe(concat('app.js')) .pipe(uglify()) .pipe(gulp.dest('dist/js'));    
  31. 31. gulp.src('app/js/**/*.coffee')        .pipe(coffee()) .pipe(concat('app.js')) .pipe(gulp.dest('test/js')) .pipe(uglify()) .pipe(gulp.dest('dist/js'));    
  32. 32. 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')); });
  33. 33. gulp.task('watch',  function()  { gulp.watch('app/js/**/*.coffee',                      ['coffee']); }); 
  34. 34. gulp.task('default',          ['coffee','watch']);     
  35. 35.  level up dependencies
  36. 36. gulp.task('css',                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); });  
  37. 37. var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    bower(); }); 
  38. 38. gulp.task('css',  ['install'],                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); });   
  39. 39. var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    bower(); }); //  Doesn't  work  as  expected 
  40. 40. our five tasks
  41. 41. ┌ │ ┤ │ └ ┬ │ └ ─ expected dependency tree
  42. 42. ┌ │ ├ │ ┼ │ ├ │ └ actual tree
  43. 43. gulp.task('stuff',  function()  {    doStuff();    });
  44. 44. //  Option  1:  Callback gulp.task('stuff',  function(done)  {    doSyncStuff()    done(err); });
  45. 45. var  Q  =  require('q'); //  Option  2:  Promise gulp.task('stuff',  function()  {    var  deferred  =  Q.defer();    doAsyncStuff(deferred.resolve);    return  deferred.promise; });
  46. 46. //  Option  3:  Return  stream gulp.task('stuff',  function()  {    var  stream  =  doStreamStuff();    return  stream; });
  47. 47. gulp.task  'stuff',  ()  -­‐>    doStreamStuff()
  48. 48. #  Get  return  stream  for  free! gulp.task  'stuff',  ()  -­‐>    doStreamStuff() gulp.task('stuff',  function()  {    return  doStreamStuff();    });
  49. 49. var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    bower(); }); 
  50. 50. var  bower  =  require('gulp-­‐bower'); gulp.task('install',  function()  {    return  bower();  //  Win! }); 
  51. 51. //  Back  to  where  we  were gulp.task('css',                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); });  
  52. 52. gulp.task('css',  ['install'],                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); }); 
  53. 53.  level up using coffee
  54. 54. //gulpfile.js gulp.task('css',  ['install'],                    function()  {    gulp.src('app/css/app.less')            .pipe(less())    .pipe(cssmin())    .pipe(gulp.dest('dist/css')); }); 
  55. 55. #  gulpfile.coffee gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  'app/css/app.less'            .pipe  less()    .pipe  cssmin()      .pipe  gulp.dest('dist/css') 
  56. 56.  gulp --require coffee-script/register
  57. 57.  more gulpfile.js //gulpfile.js require('coffee-­‐script'); require('./gulpfile.coffee');  gulp
  58. 58.  level up merging streams
  59. 59.    
  60. 60.      
  61. 61. gulp.task  'js',  ()  -­‐>    gulp.src  files.coffee            .pipe  coffee()            .pipe  concat('app.js')            .pipe  uglify()            .pipe  gulp.dest('dist/js')    
  62. 62. evtstream  =  require  'event-­‐stream'      #  and/or streamq      =  require  'streamqueue'
  63. 63. gulp.task  'js',  ()  -­‐>    gulp.src(files.coffee)            .pipe(coffee())            .pipe  concat('app.js')            .pipe  uglify()            .pipe  gulp.dest('dist/js')    
  64. 64. 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')     
  65. 65. 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')     
  66. 66. 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')     
  67. 67.  level up error handling
  68. 68. gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  less()      .pipe  cssmin()    .pipe  gulp.dest('dist/css') 
  69. 69. //  app.less .mayhem  {    font-­‐weight:  bold;    color:              @red; } }  //  too  many  '{'  ===  BOOM! 
  70. 70. [gulp]  Running  'css'... events.js:72                throw  er;  //  Unhandled  'error'                            ^ Error:  missing  opening  `{`  in  file  ./c  
  71. 71. gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  less()      .pipe  cssmin()    .pipe  gulp.dest('dist/css') 
  72. 72. 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') 
  73. 73. plumber  =  require  'gulp-­‐plumber' gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src  files.less            .pipe  plumber()  #Win!            .pipe  less()      .pipe  cssmin()    .pipe  gulp.dest('dist/css') 
  74. 74. [gulp]  Running  'css'... [gulp]  Error  in  plugin  'gulp-­‐less':    missing  opening  `{`  in  file  app.less [gulp]  Finished  'css'  in  21  ms 
  75. 75.  level up master class
  76. 76. gutil  =  require  'gulp-­‐util' 
  77. 77. 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')      
  78. 78. 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')      
  79. 79.  gulp  -­‐-­‐port=8000  -­‐-­‐dest=prod gutil.env.port  ===  8000 gutil.env.dest  ===  'prod' 
  80. 80.   echo  Total  Files:  $(      find  .  -­‐type  f  -­‐print  |  wc  -­‐l) Total  Files:  1000  echo  watch  will  vomit
  81. 81.  level up comparison
  82. 82. 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"
  83. 83. gulpfile.coffee gulp  =  require  'gulp' gutil  =  require  'gulp-­‐util' fs  =  require  'fs' path  =  require  'path' bower  =  require  'gulp-­‐bower' clean  =  require  'gulp-­‐clean' coffee  =  require  'gulp-­‐coffee' coffeelint  =  require  'gulp-­‐coffeelint' concat  =  require  'gulp-­‐concat' jade  =  require  'gulp-­‐jade' jslint  =  require  'gulp-­‐jshint' jslintReporter  =  require  'jshint-­‐stylish' less  =  require  'gulp-­‐less' cssmin  =  require  'gulp-­‐minify-­‐css' connect  =  require  'gulp-­‐connect' uglify  =  require  'gulp-­‐uglify' es  =  require  'event-­‐stream' pkg  =  require  './package.json' server  =  require  './config/server' urlrouter  =  require  'urlrouter' output  =    css:            'css/app.css'    jsApp:        'js/app.js'    jsVendor:  'js/vendor.js' files  =    coffee:      'app/js/**/*.coffee'    img:            'app/img/**/*.*'    static:      'app/static/**/*.*'    webfonts:  [        'vendor/webfonts/**/*.*'        'vendor/components/font-­‐awesome/fonts/**/*.*'    ]    jade:          'app/pages/**/*.jade'    js:        app:        ['app/js/**/*.js']        vendor:  [            'vendor/components/jquery/jquery.min.js'            'vendor/components/underscore/underscore-­‐min.js'            'vendor/components/angular/angular.min.js'            'vendor/js/**/*.js'        ]    less:        app:        'app/css/app.less'        watch:    [            'app/css/**'            'vendor/components/bootstrap/less/**'        ] config  =    jshint:        #  enforcing  options        curly:  true        eqeqeq:  true        latedef:  true        newcap:  true        noarg:  true        #  relaxing  options        boss:  true        eqnull:  true        sub:  true        #  environment/globals        browser:  true    jade:        pretty:  true        data:            js:  output.jsApp            jsVendor:  output.jsVendor            css:  output.css            pkg:  pkg    server:        port:  8000        base:  'generated'        livereload:  true        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 gulp.task  'default',  ['lint','build'] gulp.task  'run',  ['lint','build','server','watch'] gulp.task  'build',  [        'install'        'js'        'css'        'jade'        'copy'    ] gulp.task  'install',  ()  -­‐>    bower() gulp.task  'lint',  ['coffeelint','jslint'] gulp.task  'coffeelint',  ()  -­‐>    gulp.src(files.coffee)        .pipe(coffeelint())        .pipe(coffeelint.reporter()) gulp.task  'jslint',  ()  -­‐>    gulp.src(files.js.app)        .pipe(jslint(config.jshint))        .pipe(jslint.reporter(jslintReporter))     gulp.task  'jade',  ()  -­‐>    gulp.src(files.jade)        .pipe(jade(config.jade))        .pipe(gulp.dest('./generated'))        .pipe(gulp.dest('./dist')) gulp.task  'jsApp',  ()  -­‐>    es.concat(            gulp.src(files.coffee).pipe(coffee()),            gulp.src(files.js.app)        ).pipe(concat(output.jsApp))        .pipe(gulp.dest('./generated'))        .pipe(uglify())        .pipe(gulp.dest('./dist'))     gulp.task  'jsVendor',  ['install'],  ()  -­‐>    gulp.src(files.js.vendor)        .pipe(concat(output.jsVendor))        .pipe(gulp.dest('./generated'))        .pipe(gulp.dest('./dist'))     gulp.task  'js',  ['jsApp','jsVendor']     gulp.task  'css',  ['install'],  ()  -­‐>    gulp.src(files.less.app)        .pipe(plumber())        .pipe(less())        .pipe(concat(output.css))        .pipe(gulp.dest('./generated'))        .pipe(cssmin())        .pipe(gulp.dest('./dist'))     gulp.task  'clean',  ()  -­‐>    gulp.src(['./dist','./generated',  bowerDirectory()])        .pipe(clean()) gulp.task  'copy',  ['install'],  ()  -­‐>    es.concat(        gulp.src(files.img)            .pipe(gulp.dest('./generated/img'))            .pipe(gulp.dest('./dist/img')),        gulp.src(files.static)            .pipe(gulp.dest('./generated/'))            .pipe(gulp.dest('./dist/')),        gulp.src(files.webfonts)            .pipe(gulp.dest('./generated/fonts'))            .pipe(gulp.dest('./dist/fonts'))    ) gulp.task  'watch',  ()  -­‐>    gulp.watch  files.coffee,            ['coffeelint','jsApp']    gulp.watch  files.js.app,            ['jslint','jsApp']    gulp.watch  files.js.vendor,      ['jsVendor']    gulp.watch  files.jade.pages,    ['jade']    gulp.watch  files.less.watch,    ['css']    gulp.watch  [files.img,  files.webfonts,  files.static],    ['copy']     gulp.task  'server',  ['build'],  connect.server(config.server) bowerDirectory  =  ()  -­‐>    bowerpath  =  path.join(process.cwd(),  ".bowerrc")    bowerrc  =  fs.readFileSync(bowerpath)  unless  !fs.existsSync  bowerpath      bowerConfig  =  JSON.parse(bowerrc)  if  bowerrc?    bowerConfig?.directory  ||  "vendor/components"
  84. 84. 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');
  85. 85. bower            =  require  'gulp-­‐bower' coffeelint  =  require  'gulp-­‐coffeelint' clean            =  require  'gulp-­‐clean' coffee          =  require  'gulp-­‐coffee' concat          =  require  'gulp-­‐concat' connect        =  require  'gulp-­‐connect'    #          copy  included  via  .dest cssmin          =  require  'gulp-­‐minify-­‐css' jade              =  require  'gulp-­‐jade' jslint          =  require  'gulp-­‐jshint' less              =  require  'gulp-­‐less' uglify          =  require  'gulp-­‐uglify'    #        watch  included  via  .watch
  86. 86.  git  co  grunt  time  grunt  >  /dev/null real  0m5.114s user  0m4.802s sys    0m0.214s
  87. 87.  git  co  grunt  time  grunt  >  /dev/null real  0m5.114s user  0m4.802s sys    0m0.214s  git  co  gulp  time  gulp  >  /dev/null real  0m2.811s user  0m2.601s sys    0m0.241s
  88. 88. 
  89. 89. learn more  gulpjs.com  gulpjs/gulp  gulpjs
  90. 90. demo code  queenseight.com  aranasoft/queenseight  git checkout grunt  git checkout gulp
  91. 91. NEXT STEPS npm install gulp
  92. 92. dethrone grunt
  93. 93. @jayharris #dethroningGrunt jay@aranasoft.com
  94. 94. @jayharris #dethroningGrunt thank you

×