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

Let Grunt do the work, focus on the fun! Open Web Camp 2013

Let Grunt do the work, focus on the fun! Open Web Camp 2013

Google’s Dirk Ginader thinks great developers are lazy, and there’s nothing wrong with that. After all, would you rather spend your time working on the mundane stuff — like minification, linting, compilation, unit testing, etc — or actually developing your code?

In this presentation, Dirk will show you how to set up the Grunt JavaScript Task Runner so that you and your team can focus on the fun!

Ac20c97a1a7c321444013be47f1fcee6?s=128

Dirk Ginader

July 13, 2013
Tweet

Transcript

  1. Let Grunt do the work, focus on the fun! Dirk

    Ginader, Google, 2013 @ginader http://dir.kg/slides
  2. Let Grunt do the endlessly repetitive tedious tasks, focus on

    the important stuff like Accessibility! Dirk Ginader, Google, 2013
  3. Let Grunt do the work, focus on the fun! Dirk

    Ginader, Google, 2013
  4. Why Build scripts?

  5. Because great Developers are lazy.

  6. Because great Developers are lazy. FACT.

  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
  8. Build systems have been around for ages • Make •

    Maven • and so many more ... • Ant • Rake
  9. They’re all great and powerful and all...

  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/
  11. None
  12. How much I liked to configure with XML?

  13. None
  14. I’m a Front End Developer!

  15. I like Javascript

  16. I like LOVE Javascript

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

    favor:
  19. GRUNT The JavaScript Task Runner

  20. written in Javascript

  21. using the node package manager

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

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

  25. System Setup:

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

  27. None
  28. None
  29. $ npm install -g grunt-cli

  30. None
  31. Project Setup:

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

  33. package.json

  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": { } } https://npmjs.org/doc/json.html
  35. 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
  36. { "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
  37. $ npm install grunt --save-dev

  38. None
  39. { "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
  40. $ npm install install all the defined Dependencies in one

    go
  41. Gruntfile.js

  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']); };
  43. 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/
  44. None
  45. 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']); };
  46. 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']); };
  47. 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']); };
  48. let’s see what it does! $ grunt

  49. None
  50. None
  51. easy to add more $ npm i grunt-contrib-jshint --save-dev

  52. None
  53. 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']); }; https://npmjs.org/package/grunt-contrib-jshint
  54. None
  55. None
  56. tired of typing already? $ grunt watch

  57. watch: { gruntfile: { files: [ 'Gruntfile.js', 'js/myfile.js'], tasks: ['jshint']

    } } https://npmjs.org/package/grunt-contrib-watch
  58. None
  59. None
  60. None
  61. 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']); };
  62. { "name": "jQuery-Accessible-Tabs", "version": "1.9.7", "homepage": "http://github.com/ginader/Accessible-Tabs", "author": { "name":

    "Dirk Ginader", "url": "http://ginader.com" } } https://npmjs.org/doc/json.html
  63. 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']); };
  64. 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']); };
  65. 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']); https://npmjs.org/package/grunt- contrib-cssmin
  66. 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']); https://npmjs.org/package/grunt- contrib-imagemin
  67. but it’s more than just optimizations

  68. Build HTML Pages markdown: { all: { files: ['readme.markdown','version-history.markdown'], template:

    'web/template.html', dest: 'web', options: { gfm: true, codeLines: { before: '<span>', after: '</span>' } } } } https://npmjs.org/package/ grunt-markdown
  69. remove debug code removelogging: { dist: { src: 'js/jquery.tabs.min.js', dest:

    'js/jquery.tabs.min.js' } } https://npmjs.org/package/ grunt-remove-logging
  70. compile Sass/Compass // setup Compass/Sass to load from existing config.rb

    compass: { dist: { options: { config: 'config.rb' } } } https://npmjs.org/package/ grunt-contrib-compass
  71. ...but Kitt will tell you all about that in the

    next Session :-)
  72. and Livereload! https://npmjs.org/package/ grunt-contrib-livereload

  73. all done? deploy!

  74. FTP upload dance?

  75. https://npmjs.org/ package/grunt-rsync

  76. None
  77. Scaffolding

  78. $ npm install -g grunt-init

  79. many templates for grunt-init • Gruntfile • Grunt plugin •

    jQuery plugin • node.js • ...
  80. $ git clone git:// github.com/gruntjs/grunt- init-jquery.git ~/.grunt- init/jquery

  81. $ grunt-init jquery

  82. None
  83. 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?
  84. 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 • http://dir.kg/slides