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

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