SlideShare a Scribd company logo
1 of 64
Download to read offline
Let Grunt do the work,
   focus on the fun!
    Dirk Ginader, Google, 2013




                                 1
Let Grunt do the endlessly
repetitive tedious tasks, focus
   on the important stuff!
       Dirk Ginader, Google, 2013




                                    2
Let Grunt do the work,
   focus on the fun!
    Dirk Ginader, Google, 2013




                                 3
Why Build scripts?



                     4
Because great
 Developers
  are lazy.


                5
Because great
 Developers
  are lazy.
   FACT.

                6
runs script
time                                  loses
spent   writes script
        to automate
                                                  wins
         gets
         annoyed                       makes fun of geek’s
                                       complicated method
        does it
        manually


 geek              does it manually

        non-geek                              task size


                                                             7
Build systems have
    been around for ages
•   Make                   •   Ant

•   Maven                  •   Rake

•   and so many more ...




                                      8
They’re all great and
 powerful and all...


                        9
Minify with Ant
<target name="js-compile-all" description="Compile JavaScript files with Closure"
unless="skip-js-compile">
    <echo>Compiling JS files in ${input.scripts.dir} in closure...</echo>
    <apply executable="java" dest="${output.scripts.dir}">
        <arg value="-jar"/>
        <arg path="${jar.lib.dir}/closure-compiler.jar"/>
        <arg line="--js"/>
        <srcfile/>
        <arg line="--js_output_file"/>
        <targetfile/>
        <fileset dir="${output.scripts.dir}" includes="**/*-main.debug.js" />
        <mapper type="glob" from="*-main.debug.js" to="*-main.min.js"/>
    </apply>
    <echo>Finished compiling JS files</echo>
</target>




            http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/

                                                                                                              10
11
How much I liked to
configure with XML?


                      12
13
I’m a Front End
  Developer!


                  14
I like Javascript



                    15
I like LOVE Javascript



                         16
17
Just one year ago
Ben Alman did me a
    great favor:


                     18
GRUNT
The JavaScript Task Runner


                             19
20
written in Javascript



                        21
using the node
package manager


                  22
FAST adoption rate
•   jQuery

•   Modernizr

•   Adobe

•   twitter

•   ...




                          23
because it’s easy!



                     24
System Setup:



                25
download and install
   node.js from:
 http://nodejs.org/


                       26
$ npm install -g grunt-cli




                             27
Project Setup:



                 28
2 important Files:
   package.json
    Gruntfile.js


                     29
package.json



               30
{
    "name": "jQuery-Accessible-Tabs",
    "version": "1.9.7",
    "homepage": "http://github.com/ginader/Accessible-Tabs",
    "author": {
      "name": "Dirk Ginader",
      "url": "http://ginader.com"
    },
    "devDependencies": {

    }
}




                         https://npmjs.org/doc/json.html
                                                               31
Gives you:

• Variables you can use in your script
  i.e. version and name
• Dev Dependencies that allows you to
  quickly install all required npm modules




                                             32
{
    "name": "jQuery-Accessible-Tabs",
    "version": "1.9.7",
    "homepage": "http://github.com/ginader/Accessible-Tabs",
    "author": {
      "name": "Dirk Ginader",
      "url": "http://ginader.com"
    },
    "devDependencies": {

    }
}




                         https://npmjs.org/doc/json.html
                                                               33
$ npm install grunt --save-dev




                                 34
{
    "name": "jQuery-Accessible-Tabs",
    "version": "1.9.7",
    "homepage": "http://github.com/ginader/Accessible-Tabs",
    "author": {
      "name": "Dirk Ginader",
      "url": "http://ginader.com"
    },
    "devDependencies": {
      "grunt": "~0.4.0"
    }
}




                         https://npmjs.org/doc/json.html
                                                               35
install all the defined
     Dependencies in one go

$ npm install




                               36
Gruntfile.js



              37
Minify with Grunt
  module.exports = function(grunt) {
     grunt.initConfig({
       uglify: {
         dist: {
           src: 'dist/myfile.js',
           dest: 'dist/myfile.min.js'
         },
       }
     });
     grunt.loadNpmTasks('grunt-contrib-uglify');
     grunt.registerTask('default', ['uglify']);
  };




http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/

                                                                                                  38
Minify with Ant
<target name="js-compile-all" description="Compile JavaScript files with Closure"
unless="skip-js-compile">
    <echo>Compiling JS files in ${input.scripts.dir} in closure...</echo>
    <apply executable="java" dest="${output.scripts.dir}">
        <arg value="-jar"/>
        <arg path="${jar.lib.dir}/closure-compiler.jar"/>
        <arg line="--js"/>
        <srcfile/>
        <arg line="--js_output_file"/>
        <targetfile/>
        <fileset dir="${output.scripts.dir}" includes="**/*-main.debug.js" />
        <mapper type="glob" from="*-main.debug.js" to="*-main.min.js"/>
    </apply>
    <echo>Finished compiling JS files</echo>
</target>




            http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/

                                                                                                              39
40
Minify with Grunt
  module.exports = function(grunt) {
     grunt.initConfig({
       uglify: {
         dist: {
           src: 'dist/myfile.js',
           dest: 'dist/myfile.min.js'
         }
       }
     });
     grunt.loadNpmTasks('grunt-contrib-uglify');
     grunt.registerTask('default', ['uglify']);
  };




http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/

                                                                                                  41
Minify with Grunt
  module.exports = function(grunt) {
     grunt.initConfig({
       uglify: {
         dist: {
           src: 'dist/myfile.js',
           dest: 'dist/myfile.min.js'
         }
       }
     });
     grunt.loadNpmTasks('grunt-contrib-uglify');
     grunt.registerTask('default', ['uglify']);
  };




http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/

                                                                                                  42
Minify with Grunt
  module.exports = function(grunt) {
     grunt.initConfig({
       uglify: {
         dist: {
           src: 'dist/myfile.js',
           dest: 'dist/myfile.min.js'
         }
       }
     });
     grunt.loadNpmTasks('grunt-contrib-uglify');
     grunt.registerTask('default', ['uglify']);
  };




http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/

                                                                                                  43
44
easy to add more
$ npm i grunt-contrib-jshint --save-dev




                                          45
add JS Linting
module.exports = function(grunt) {
   grunt.initConfig({
     jshint: {
        all: ['*.js']
     },
     uglify: {
        dist: {
          src: 'myfile.js',
          dest: 'myfile.min.js'
        }
     }
   });
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-contrib-jshint');
   grunt.registerTask('default', ['jshint','uglify']);
};




                                                         46
add data from package.json
module.exports = function(grunt) {
   grunt.initConfig({
     pkg: grunt.file.readJSON('package.json'),
     jshint: {
        all: ['*.js']
     },
     uglify: {
       options: {
          banner: '/*! <%= pkg.name %>' +
             ' <%= grunt.template.today("yyyy-mm-dd") %> */n'
        },
        dist: {
           src: 'myfile.js',
           dest: 'myfile.min.js'
        }
     }
   });
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-contrib-jshint');
   grunt.registerTask('default', ['jshint','uglify']);
};



                                                                 47
add data from package.json
module.exports = function(grunt) {
   grunt.initConfig({
     pkg: grunt.file.readJSON('package.json'),
     jshint: {
        all: ['*.js']
     },
     uglify: {
        options: {
           banner: '/*! <%= pkg.name %>' +
             ' <%= grunt.template.today("yyyy-mm-dd") %> */n'
        },
        dist: {
           src: '<%= pkg.name %>.js',
           dest: '<%= pkg.name %>.min.js'
        }
     }
   });
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-contrib-jshint');
   grunt.registerTask('default', ['jshint','uglify']);
};



                                                                 48
add data from package.json
module.exports = function(grunt) {
   grunt.initConfig({
     pkg: grunt.file.readJSON('package.json'),
     jshint: {
        all: ['*.js']
     },
     uglify: {
        options: {
           banner: '/*! <%= pkg.name %>' +
             ' <%= grunt.template.today("yyyy-mm-dd") %> */n'
        },
        dist: {
           src: '<%= pkg.name %>.js',
           dest: '<%= pkg.name %>.<%= pkg.version %>.min.js'
        }
     }
   });
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-contrib-jshint');
   grunt.registerTask('default', ['jshint','uglify']);
};



                                                                 49
minify and combine CSS
  cssmin: {
    compress: {
      options: {
        banner: '<%= banner %>'
      },
      files: {
        'project.min.css': ['1.css','2.css', '...']
      }
    }
  }


grunt.loadNpmTasks('grunt-contrib-cssmin');

grunt.registerTask('default', ['jshint','uglify', 'cssmin']);




                                                                50
optimize Images
imagemin: {
  dist: {
    options: {
      optimizationLevel: 3
    },
    files: {
      // 'destination': 'source'
      'dist/img.png': 'src/img.png',
      'dist/img.jpg': 'src/img.jpg'
    }
  }
}

grunt.registerTask('default', ['imagemin']);




                                               51
but it’s more than just
     optimizations


                          52
render markdown to
       HTML
markdown: {
  all: {
    files: ['readme.markdown','version-history.markdown'],
    template: 'web/template.html',
    dest: 'web',
    options: {
      gfm: true,
      codeLines: {
         before: '<span>',
         after: '</span>'
      }
    }
  }
}




                                                             53
remove debug code
   removelogging: {
     dist: {
       src: 'js/jquery.tabs.min.js',
       dest: 'js/jquery.tabs.min.js'
     }
   }




                                       54
compile Sass/Compass
 // setup Compass/Sass to load from existing config.rb
 compass: {
   dist: {
     options: {
       config: 'config.rb'
     }
   }
 }




                                                         55
and Livereload!




                  56
Scaffolding



              57
$ npm install -g grunt-init




                              58
many templates for
          grunt-init
•   Gruntfile

•   Grunt plugin

•   jQuery plugin

•   node.js

•   ...




                           59
$ git clone git://
github.com/gruntjs/grunt-
init-jquery.git ~/.grunt-
init/jquery




                            60
$ grunt-init jquery




                      61
62
Thank you! Questions?

The opinions I expressed here represent my own
   and not necessarily those of my employer.

        btw: We’re hiring! Talk to me :-)
                                                 63
Resources
•   Grunt: http://gruntjs.com/
•   Great article: http://dir.kg/grunt.workflow
•   Extending Grunt big time: http://yeoman.io
•   Me: http://dir.kg/me
    •   @ginader on twitter
    •   the example projects: http://github.com/ginader/
    •   http://ginader.com


                                                           64

More Related Content

What's hot

Puppeteer can automate that! - AmsterdamJS
Puppeteer can automate that! - AmsterdamJSPuppeteer can automate that! - AmsterdamJS
Puppeteer can automate that! - AmsterdamJSÖnder Ceylan
 
Automating WordPress Theme Development
Automating WordPress Theme DevelopmentAutomating WordPress Theme Development
Automating WordPress Theme DevelopmentHardeep Asrani
 
Developing for Mobile
Developing for MobileDeveloping for Mobile
Developing for MobileRemy Sharp
 
Puppeteer can automate that! - HolyJS Piter 2020
Puppeteer can automate that! - HolyJS Piter 2020Puppeteer can automate that! - HolyJS Piter 2020
Puppeteer can automate that! - HolyJS Piter 2020Önder Ceylan
 
Ten practical ways to improve front-end performance
Ten practical ways to improve front-end performanceTen practical ways to improve front-end performance
Ten practical ways to improve front-end performanceAndrew Rota
 
Bower - A package manager for the web
Bower - A package manager for the webBower - A package manager for the web
Bower - A package manager for the webLarry Nung
 
Bower & Grunt - A practical workflow
Bower & Grunt - A practical workflowBower & Grunt - A practical workflow
Bower & Grunt - A practical workflowRiccardo Coppola
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widgetTudor Barbu
 
Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Ovadiah Myrgorod
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Derek Willian Stavis
 
Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)Future Insights
 
Mehr Performance für WordPress - WordCamp Köln
Mehr Performance für WordPress - WordCamp KölnMehr Performance für WordPress - WordCamp Köln
Mehr Performance für WordPress - WordCamp KölnWalter Ebert
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
Instant and offline apps with Service Worker
Instant and offline apps with Service WorkerInstant and offline apps with Service Worker
Instant and offline apps with Service WorkerChang W. Doh
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bitsjungkees
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloJavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloRobert Nyman
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseAaron Silverman
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaRobert Nyman
 

What's hot (20)

Puppeteer can automate that! - AmsterdamJS
Puppeteer can automate that! - AmsterdamJSPuppeteer can automate that! - AmsterdamJS
Puppeteer can automate that! - AmsterdamJS
 
Automating WordPress Theme Development
Automating WordPress Theme DevelopmentAutomating WordPress Theme Development
Automating WordPress Theme Development
 
Developing for Mobile
Developing for MobileDeveloping for Mobile
Developing for Mobile
 
Puppeteer can automate that! - HolyJS Piter 2020
Puppeteer can automate that! - HolyJS Piter 2020Puppeteer can automate that! - HolyJS Piter 2020
Puppeteer can automate that! - HolyJS Piter 2020
 
Ten practical ways to improve front-end performance
Ten practical ways to improve front-end performanceTen practical ways to improve front-end performance
Ten practical ways to improve front-end performance
 
Bower - A package manager for the web
Bower - A package manager for the webBower - A package manager for the web
Bower - A package manager for the web
 
Bower & Grunt - A practical workflow
Bower & Grunt - A practical workflowBower & Grunt - A practical workflow
Bower & Grunt - A practical workflow
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!
 
Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)
 
Mehr Performance für WordPress - WordCamp Köln
Mehr Performance für WordPress - WordCamp KölnMehr Performance für WordPress - WordCamp Köln
Mehr Performance für WordPress - WordCamp Köln
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
Bower power
Bower powerBower power
Bower power
 
Instant and offline apps with Service Worker
Instant and offline apps with Service WorkerInstant and offline apps with Service Worker
Instant and offline apps with Service Worker
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bits
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloJavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash Course
 
Front-end tools
Front-end toolsFront-end tools
Front-end tools
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
 

Similar to Let Grunt do the work, focus on the fun!

Grunt & Front-end Workflow
Grunt & Front-end WorkflowGrunt & Front-end Workflow
Grunt & Front-end WorkflowPagepro
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and PracticeBo-Yi Wu
 
Workflow para desenvolvimento Web & Mobile usando grunt.js
Workflow para desenvolvimento Web & Mobile usando grunt.jsWorkflow para desenvolvimento Web & Mobile usando grunt.js
Workflow para desenvolvimento Web & Mobile usando grunt.jsDavidson Fellipe
 
Javascript is your (Auto)mate
Javascript is your (Auto)mateJavascript is your (Auto)mate
Javascript is your (Auto)mateCodemotion
 
Automating Front-End Workflow
Automating Front-End WorkflowAutomating Front-End Workflow
Automating Front-End WorkflowDimitris Tsironis
 
The Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build ScriptThe Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build ScriptDocker, Inc.
 
Intro to go web assembly
Intro to go web assemblyIntro to go web assembly
Intro to go web assemblyChe-Chia Chang
 
JS digest. February 2017
JS digest. February 2017JS digest. February 2017
JS digest. February 2017ElifTech
 
What makes me "Grunt"?
What makes me "Grunt"? What makes me "Grunt"?
What makes me "Grunt"? Fabien Doiron
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsAlessandro Molina
 
Delivering Go.CD with Terraform and Docker
Delivering Go.CD with Terraform and DockerDelivering Go.CD with Terraform and Docker
Delivering Go.CD with Terraform and DockerJorrit Salverda
 
Coscup x ruby conf tw 2021 google cloud buildpacks 剖析與實踐
Coscup x ruby conf tw 2021  google cloud buildpacks 剖析與實踐Coscup x ruby conf tw 2021  google cloud buildpacks 剖析與實踐
Coscup x ruby conf tw 2021 google cloud buildpacks 剖析與實踐KAI CHU CHUNG
 
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis OverviewLeo Lorieri
 
ContainerDayVietnam2016: Django Development with Docker
ContainerDayVietnam2016: Django Development with DockerContainerDayVietnam2016: Django Development with Docker
ContainerDayVietnam2016: Django Development with DockerDocker-Hanoi
 
JavaScript Modules Past, Present and Future
JavaScript Modules Past, Present and FutureJavaScript Modules Past, Present and Future
JavaScript Modules Past, Present and FutureIgalia
 
Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Cosimo Streppone
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Halil Kaya
 
Web development - technologies and tools
Web development - technologies and toolsWeb development - technologies and tools
Web development - technologies and toolsYoann Gotthilf
 

Similar to Let Grunt do the work, focus on the fun! (20)

Grunt & Front-end Workflow
Grunt & Front-end WorkflowGrunt & Front-end Workflow
Grunt & Front-end Workflow
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Workflow para desenvolvimento Web & Mobile usando grunt.js
Workflow para desenvolvimento Web & Mobile usando grunt.jsWorkflow para desenvolvimento Web & Mobile usando grunt.js
Workflow para desenvolvimento Web & Mobile usando grunt.js
 
Grunt All Day
Grunt All DayGrunt All Day
Grunt All Day
 
Javascript is your (Auto)mate
Javascript is your (Auto)mateJavascript is your (Auto)mate
Javascript is your (Auto)mate
 
Grunt to automate JS build
Grunt to automate JS buildGrunt to automate JS build
Grunt to automate JS build
 
Automating Front-End Workflow
Automating Front-End WorkflowAutomating Front-End Workflow
Automating Front-End Workflow
 
The Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build ScriptThe Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build Script
 
Intro to go web assembly
Intro to go web assemblyIntro to go web assembly
Intro to go web assembly
 
JS digest. February 2017
JS digest. February 2017JS digest. February 2017
JS digest. February 2017
 
What makes me "Grunt"?
What makes me "Grunt"? What makes me "Grunt"?
What makes me "Grunt"?
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
 
Delivering Go.CD with Terraform and Docker
Delivering Go.CD with Terraform and DockerDelivering Go.CD with Terraform and Docker
Delivering Go.CD with Terraform and Docker
 
Coscup x ruby conf tw 2021 google cloud buildpacks 剖析與實踐
Coscup x ruby conf tw 2021  google cloud buildpacks 剖析與實踐Coscup x ruby conf tw 2021  google cloud buildpacks 剖析與實踐
Coscup x ruby conf tw 2021 google cloud buildpacks 剖析與實踐
 
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
 
ContainerDayVietnam2016: Django Development with Docker
ContainerDayVietnam2016: Django Development with DockerContainerDayVietnam2016: Django Development with Docker
ContainerDayVietnam2016: Django Development with Docker
 
JavaScript Modules Past, Present and Future
JavaScript Modules Past, Present and FutureJavaScript Modules Past, Present and Future
JavaScript Modules Past, Present and Future
 
Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36
 
Web development - technologies and tools
Web development - technologies and toolsWeb development - technologies and tools
Web development - technologies and tools
 

More from Dirk Ginader

Teach your Browser new tricks
Teach your Browser new tricksTeach your Browser new tricks
Teach your Browser new tricksDirk Ginader
 
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
HTML5 Dev Conf - Sass, Compass &  the new Webdev toolsHTML5 Dev Conf - Sass, Compass &  the new Webdev tools
HTML5 Dev Conf - Sass, Compass & the new Webdev toolsDirk Ginader
 
Sass, Compass and the new tools - Open Web Camp IV
Sass, Compass and the new tools - Open Web Camp IVSass, Compass and the new tools - Open Web Camp IV
Sass, Compass and the new tools - Open Web Camp IVDirk Ginader
 
The accessibility features of Yahoo! Finance
The accessibility features of Yahoo! FinanceThe accessibility features of Yahoo! Finance
The accessibility features of Yahoo! FinanceDirk Ginader
 
Javascript done right
Javascript done rightJavascript done right
Javascript done rightDirk Ginader
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Dirk Ginader
 
the 5 layers of web accessibility - Open Web Camp II
the 5 layers of web accessibility - Open Web Camp IIthe 5 layers of web accessibility - Open Web Camp II
the 5 layers of web accessibility - Open Web Camp IIDirk Ginader
 
Das Web Als Datenbank Mit Yql Und Pipes
Das Web Als Datenbank Mit Yql Und PipesDas Web Als Datenbank Mit Yql Und Pipes
Das Web Als Datenbank Mit Yql Und PipesDirk Ginader
 
Die 5 Ebenen Barriererfreier Web Entwicklung
Die 5 Ebenen Barriererfreier Web EntwicklungDie 5 Ebenen Barriererfreier Web Entwicklung
Die 5 Ebenen Barriererfreier Web EntwicklungDirk Ginader
 
The 5 Layers of Web Accessibility
The 5 Layers of Web AccessibilityThe 5 Layers of Web Accessibility
The 5 Layers of Web AccessibilityDirk Ginader
 
Accessible Javascript with and without WAI ARIA
Accessible Javascript with and without WAI ARIAAccessible Javascript with and without WAI ARIA
Accessible Javascript with and without WAI ARIADirk Ginader
 
Avoiding common Accessibility mistakes
Avoiding common Accessibility mistakesAvoiding common Accessibility mistakes
Avoiding common Accessibility mistakesDirk Ginader
 
Accessible Javascript using Frameworks - Barcamp London 5
Accessible Javascript using Frameworks - Barcamp London 5Accessible Javascript using Frameworks - Barcamp London 5
Accessible Javascript using Frameworks - Barcamp London 5Dirk Ginader
 
Accessible Javascript mit Frameworks - Best of Accessibility 2008
Accessible Javascript mit Frameworks - Best of Accessibility 2008Accessible Javascript mit Frameworks - Best of Accessibility 2008
Accessible Javascript mit Frameworks - Best of Accessibility 2008Dirk Ginader
 
Accessible Javascript - Barcamp Brighton 2
Accessible Javascript - Barcamp Brighton 2Accessible Javascript - Barcamp Brighton 2
Accessible Javascript - Barcamp Brighton 2Dirk Ginader
 

More from Dirk Ginader (15)

Teach your Browser new tricks
Teach your Browser new tricksTeach your Browser new tricks
Teach your Browser new tricks
 
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
HTML5 Dev Conf - Sass, Compass &  the new Webdev toolsHTML5 Dev Conf - Sass, Compass &  the new Webdev tools
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
 
Sass, Compass and the new tools - Open Web Camp IV
Sass, Compass and the new tools - Open Web Camp IVSass, Compass and the new tools - Open Web Camp IV
Sass, Compass and the new tools - Open Web Camp IV
 
The accessibility features of Yahoo! Finance
The accessibility features of Yahoo! FinanceThe accessibility features of Yahoo! Finance
The accessibility features of Yahoo! Finance
 
Javascript done right
Javascript done rightJavascript done right
Javascript done right
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010
 
the 5 layers of web accessibility - Open Web Camp II
the 5 layers of web accessibility - Open Web Camp IIthe 5 layers of web accessibility - Open Web Camp II
the 5 layers of web accessibility - Open Web Camp II
 
Das Web Als Datenbank Mit Yql Und Pipes
Das Web Als Datenbank Mit Yql Und PipesDas Web Als Datenbank Mit Yql Und Pipes
Das Web Als Datenbank Mit Yql Und Pipes
 
Die 5 Ebenen Barriererfreier Web Entwicklung
Die 5 Ebenen Barriererfreier Web EntwicklungDie 5 Ebenen Barriererfreier Web Entwicklung
Die 5 Ebenen Barriererfreier Web Entwicklung
 
The 5 Layers of Web Accessibility
The 5 Layers of Web AccessibilityThe 5 Layers of Web Accessibility
The 5 Layers of Web Accessibility
 
Accessible Javascript with and without WAI ARIA
Accessible Javascript with and without WAI ARIAAccessible Javascript with and without WAI ARIA
Accessible Javascript with and without WAI ARIA
 
Avoiding common Accessibility mistakes
Avoiding common Accessibility mistakesAvoiding common Accessibility mistakes
Avoiding common Accessibility mistakes
 
Accessible Javascript using Frameworks - Barcamp London 5
Accessible Javascript using Frameworks - Barcamp London 5Accessible Javascript using Frameworks - Barcamp London 5
Accessible Javascript using Frameworks - Barcamp London 5
 
Accessible Javascript mit Frameworks - Best of Accessibility 2008
Accessible Javascript mit Frameworks - Best of Accessibility 2008Accessible Javascript mit Frameworks - Best of Accessibility 2008
Accessible Javascript mit Frameworks - Best of Accessibility 2008
 
Accessible Javascript - Barcamp Brighton 2
Accessible Javascript - Barcamp Brighton 2Accessible Javascript - Barcamp Brighton 2
Accessible Javascript - Barcamp Brighton 2
 

Recently uploaded

Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 

Recently uploaded (20)

Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 

Let Grunt do the work, focus on the fun!

  • 1. Let Grunt do the work, focus on the fun! Dirk Ginader, Google, 2013 1
  • 2. Let Grunt do the endlessly repetitive tedious tasks, focus on the important stuff! Dirk Ginader, Google, 2013 2
  • 3. Let Grunt do the work, focus on the fun! Dirk Ginader, Google, 2013 3
  • 6. Because great Developers are lazy. FACT. 6
  • 7. runs script time loses spent writes script to automate wins gets annoyed makes fun of geek’s complicated method does it manually geek does it manually non-geek task size 7
  • 8. Build systems have been around for ages • Make • Ant • Maven • Rake • and so many more ... 8
  • 9. They’re all great and powerful and all... 9
  • 10. Minify with Ant <target name="js-compile-all" description="Compile JavaScript files with Closure" unless="skip-js-compile"> <echo>Compiling JS files in ${input.scripts.dir} in closure...</echo> <apply executable="java" dest="${output.scripts.dir}"> <arg value="-jar"/> <arg path="${jar.lib.dir}/closure-compiler.jar"/> <arg line="--js"/> <srcfile/> <arg line="--js_output_file"/> <targetfile/> <fileset dir="${output.scripts.dir}" includes="**/*-main.debug.js" /> <mapper type="glob" from="*-main.debug.js" to="*-main.min.js"/> </apply> <echo>Finished compiling JS files</echo> </target> http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 10
  • 11. 11
  • 12. How much I liked to configure with XML? 12
  • 13. 13
  • 14. I’m a Front End Developer! 14
  • 16. I like LOVE Javascript 16
  • 17. 17
  • 18. Just one year ago Ben Alman did me a great favor: 18
  • 20. 20
  • 23. FAST adoption rate • jQuery • Modernizr • Adobe • twitter • ... 23
  • 26. download and install node.js from: http://nodejs.org/ 26
  • 27. $ npm install -g grunt-cli 27
  • 29. 2 important Files: package.json Gruntfile.js 29
  • 31. { "name": "jQuery-Accessible-Tabs", "version": "1.9.7", "homepage": "http://github.com/ginader/Accessible-Tabs", "author": { "name": "Dirk Ginader", "url": "http://ginader.com" }, "devDependencies": { } } https://npmjs.org/doc/json.html 31
  • 32. Gives you: • Variables you can use in your script i.e. version and name • Dev Dependencies that allows you to quickly install all required npm modules 32
  • 33. { "name": "jQuery-Accessible-Tabs", "version": "1.9.7", "homepage": "http://github.com/ginader/Accessible-Tabs", "author": { "name": "Dirk Ginader", "url": "http://ginader.com" }, "devDependencies": { } } https://npmjs.org/doc/json.html 33
  • 34. $ npm install grunt --save-dev 34
  • 35. { "name": "jQuery-Accessible-Tabs", "version": "1.9.7", "homepage": "http://github.com/ginader/Accessible-Tabs", "author": { "name": "Dirk Ginader", "url": "http://ginader.com" }, "devDependencies": { "grunt": "~0.4.0" } } https://npmjs.org/doc/json.html 35
  • 36. install all the defined Dependencies in one go $ npm install 36
  • 38. Minify with Grunt module.exports = function(grunt) { grunt.initConfig({ uglify: { dist: { src: 'dist/myfile.js', dest: 'dist/myfile.min.js' }, } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['uglify']); }; http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 38
  • 39. Minify with Ant <target name="js-compile-all" description="Compile JavaScript files with Closure" unless="skip-js-compile"> <echo>Compiling JS files in ${input.scripts.dir} in closure...</echo> <apply executable="java" dest="${output.scripts.dir}"> <arg value="-jar"/> <arg path="${jar.lib.dir}/closure-compiler.jar"/> <arg line="--js"/> <srcfile/> <arg line="--js_output_file"/> <targetfile/> <fileset dir="${output.scripts.dir}" includes="**/*-main.debug.js" /> <mapper type="glob" from="*-main.debug.js" to="*-main.min.js"/> </apply> <echo>Finished compiling JS files</echo> </target> http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 39
  • 40. 40
  • 41. Minify with Grunt module.exports = function(grunt) { grunt.initConfig({ uglify: { dist: { src: 'dist/myfile.js', dest: 'dist/myfile.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['uglify']); }; http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 41
  • 42. Minify with Grunt module.exports = function(grunt) { grunt.initConfig({ uglify: { dist: { src: 'dist/myfile.js', dest: 'dist/myfile.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['uglify']); }; http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 42
  • 43. Minify with Grunt module.exports = function(grunt) { grunt.initConfig({ uglify: { dist: { src: 'dist/myfile.js', dest: 'dist/myfile.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['uglify']); }; http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 43
  • 44. 44
  • 45. easy to add more $ npm i grunt-contrib-jshint --save-dev 45
  • 46. add JS Linting module.exports = function(grunt) { grunt.initConfig({ jshint: { all: ['*.js'] }, uglify: { dist: { src: 'myfile.js', dest: 'myfile.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.registerTask('default', ['jshint','uglify']); }; 46
  • 47. add data from package.json module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), jshint: { all: ['*.js'] }, uglify: { options: { banner: '/*! <%= pkg.name %>' + ' <%= grunt.template.today("yyyy-mm-dd") %> */n' }, dist: { src: 'myfile.js', dest: 'myfile.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.registerTask('default', ['jshint','uglify']); }; 47
  • 48. add data from package.json module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), jshint: { all: ['*.js'] }, uglify: { options: { banner: '/*! <%= pkg.name %>' + ' <%= grunt.template.today("yyyy-mm-dd") %> */n' }, dist: { src: '<%= pkg.name %>.js', dest: '<%= pkg.name %>.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.registerTask('default', ['jshint','uglify']); }; 48
  • 49. add data from package.json module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), jshint: { all: ['*.js'] }, uglify: { options: { banner: '/*! <%= pkg.name %>' + ' <%= grunt.template.today("yyyy-mm-dd") %> */n' }, dist: { src: '<%= pkg.name %>.js', dest: '<%= pkg.name %>.<%= pkg.version %>.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.registerTask('default', ['jshint','uglify']); }; 49
  • 50. minify and combine CSS cssmin: { compress: { options: { banner: '<%= banner %>' }, files: { 'project.min.css': ['1.css','2.css', '...'] } } } grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.registerTask('default', ['jshint','uglify', 'cssmin']); 50
  • 51. optimize Images imagemin: { dist: { options: { optimizationLevel: 3 }, files: { // 'destination': 'source' 'dist/img.png': 'src/img.png', 'dist/img.jpg': 'src/img.jpg' } } } grunt.registerTask('default', ['imagemin']); 51
  • 52. but it’s more than just optimizations 52
  • 53. render markdown to HTML markdown: { all: { files: ['readme.markdown','version-history.markdown'], template: 'web/template.html', dest: 'web', options: { gfm: true, codeLines: { before: '<span>', after: '</span>' } } } } 53
  • 54. remove debug code removelogging: { dist: { src: 'js/jquery.tabs.min.js', dest: 'js/jquery.tabs.min.js' } } 54
  • 55. compile Sass/Compass // setup Compass/Sass to load from existing config.rb compass: { dist: { options: { config: 'config.rb' } } } 55
  • 58. $ npm install -g grunt-init 58
  • 59. many templates for grunt-init • Gruntfile • Grunt plugin • jQuery plugin • node.js • ... 59
  • 60. $ git clone git:// github.com/gruntjs/grunt- init-jquery.git ~/.grunt- init/jquery 60
  • 62. 62
  • 63. Thank you! Questions? The opinions I expressed here represent my own and not necessarily those of my employer. btw: We’re hiring! Talk to me :-) 63
  • 64. Resources • Grunt: http://gruntjs.com/ • Great article: http://dir.kg/grunt.workflow • Extending Grunt big time: http://yeoman.io • Me: http://dir.kg/me • @ginader on twitter • the example projects: http://github.com/ginader/ • http://ginader.com 64