SlideShare uma empresa Scribd logo
1 de 64
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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
 

Último

Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 

Último (20)

Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 

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