Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Why Build scripts? 4

Slide 5

Slide 5 text

Because great Developers are lazy. 5

Slide 6

Slide 6 text

Because great Developers are lazy. FACT. 6

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Build systems have been around for ages • Make • Maven • and so many more ... • Ant • Rake 8

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Minify with Ant Compiling JS files in ${input.scripts.dir} in closure... Finished compiling JS files http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 10

Slide 11

Slide 11 text

11

Slide 12

Slide 12 text

How much I liked to configure with XML? 12

Slide 13

Slide 13 text

13

Slide 14

Slide 14 text

I’m a Front End Developer! 14

Slide 15

Slide 15 text

I like Javascript 15

Slide 16

Slide 16 text

I like LOVE Javascript 16

Slide 17

Slide 17 text

17

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

GRUNT The JavaScript Task Runner 19

Slide 20

Slide 20 text

20

Slide 21

Slide 21 text

written in Javascript 21

Slide 22

Slide 22 text

using the node package manager 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

because it’s easy! 24

Slide 25

Slide 25 text

System Setup: 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

$ npm install -g grunt-cli 27

Slide 28

Slide 28 text

Project Setup: 28

Slide 29

Slide 29 text

2 important Files: package.json Gruntfile.js 29

Slide 30

Slide 30 text

package.json 30

Slide 31

Slide 31 text

{ "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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

{ "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

Slide 34

Slide 34 text

$ npm install grunt --save-dev 34

Slide 35

Slide 35 text

{ "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

Slide 36

Slide 36 text

$ npm install install all the defined Dependencies in one go 36

Slide 37

Slide 37 text

Gruntfile.js 37

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Minify with Ant Compiling JS files in ${input.scripts.dir} in closure... Finished compiling JS files http://mechanics.flite.com/blog/2012/06/19/why-we-use-node-dot-js-and-grunt-to-build-javascript/ 39

Slide 40

Slide 40 text

40

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

44

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

but it’s more than just optimizations 52

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

and Livereload! 56

Slide 57

Slide 57 text

Scaffolding 57

Slide 58

Slide 58 text

$ npm install -g grunt-init 58

Slide 59

Slide 59 text

many templates for grunt-init • Gruntfile • Grunt plugin • jQuery plugin • node.js • ... 59

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

$ grunt-init jquery 61

Slide 62

Slide 62 text

62

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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