Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Let Grunt do the work, focus on the fun!

Let Grunt do the work, focus on the fun!

Introduction to Grunt, the Javascript Task Runner
HTML5 Developer Conference 2013

Ac20c97a1a7c321444013be47f1fcee6?s=128

Dirk Ginader

April 03, 2013
Tweet

More Decks by Dirk Ginader

Other Decks in Technology

Transcript

  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
  4. Why Build scripts? 4

  5. Because great Developers are lazy. 5

  6. Because great Developers are lazy. FACT. 6

  7. time spent task size non-geek geek does it manually makes

    fun of geek’s complicated method loses does it manually gets annoyed writes script to automate runs script wins 7
  8. Build systems have been around for ages • Make •

    Maven • and so many more ... • Ant • Rake 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

  15. I like Javascript 15

  16. I like LOVE Javascript 16

  17. 17

  18. Just one year ago Ben Alman did me a great

    favor: 18
  19. GRUNT The JavaScript Task Runner 19

  20. 20

  21. written in Javascript 21

  22. using the node package manager 22

  23. FAST adoption rate • jQuery • Modernizr • Adobe •

    twitter • ... 23
  24. because it’s easy! 24

  25. System Setup: 25

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

  27. $ npm install -g grunt-cli 27

  28. Project Setup: 28

  29. 2 important Files: package.json Gruntfile.js 29

  30. package.json 30

  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. $ npm install install all the defined Dependencies in one

    go 36
  37. Gruntfile.js 37

  38. Minify with Grunt http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 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']); }; 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 http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 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']); }; 41
  42. Minify with Grunt http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 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']); }; 42
  43. Minify with Grunt http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 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']); }; 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
  56. and Livereload! 56

  57. Scaffolding 57

  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

  61. $ grunt-init jquery 61

  62. 62

  63. The opinions I expressed here represent my own and not

    necessarily those of my employer. btw: We’re hiring! Talk to me :-) Thank you! Questions? 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