Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Let Grunt do the work, focus on the fun!
Search
Dirk Ginader
April 03, 2013
Technology
5
9.9k
Let Grunt do the work, focus on the fun!
Introduction to Grunt, the Javascript Task Runner
HTML5 Developer Conference 2013
Dirk Ginader
April 03, 2013
Tweet
Share
More Decks by Dirk Ginader
See All by Dirk Ginader
Let Grunt do the work, focus on the fun! Open Web Camp 2013
ginader
0
73
Sass, Compass and the new tools - Open Web Camp IV
ginader
3
190
Javascript done right - Open Web Camp III
ginader
3
160
Other Decks in Technology
See All in Technology
AWS Summit Japan 2025 Community Stage - App workflow automation by AWS Step Functions
matsuihidetoshi
1
220
VISITS_AIIoTビジネス共創ラボ登壇資料.pdf
iotcomjpadmin
0
160
rubygem開発で鍛える設計力
joker1007
2
190
Snowflake Summit 2025 データエンジニアリング関連新機能紹介 / Snowflake Summit 2025 What's New about Data Engineering
tiltmax3
0
300
GitHub Copilot の概要
tomokusaba
1
130
Definition of Done
kawaguti
PRO
6
480
AWS アーキテクチャ作図入門/aws-architecture-diagram-101
ma2shita
29
10k
Observability infrastructure behind the trillion-messages scale Kafka platform
lycorptech_jp
PRO
0
130
25分で解説する「最小権限の原則」を実現するための AWS「ポリシー」大全 / 20250625-aws-summit-aws-policy
opelab
9
1.1k
Amazon S3標準/ S3 Tables/S3 Express One Zoneを使ったログ分析
shigeruoda
3
450
Amazon Bedrockで実現する 新たな学習体験
kzkmaeda
1
500
ひとり情シスなCTOがLLMと始めるオペレーション最適化 / CTO's LLM-Powered Ops
yamitzky
0
420
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
299
21k
It's Worth the Effort
3n
185
28k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
930
How GitHub (no longer) Works
holman
314
140k
Side Projects
sachag
455
42k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
The Language of Interfaces
destraynor
158
25k
Transcript
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
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
Build systems have been around for ages • Make •
Maven • and so many more ... • Ant • Rake 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
$ npm install install all the defined Dependencies in one
go 36
Gruntfile.js 37
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
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 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
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
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
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
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
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