Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
89
Sass, Compass and the new tools - Open Web Camp IV
ginader
3
210
Javascript done right - Open Web Camp III
ginader
3
160
Other Decks in Technology
See All in Technology
A Compass of Thought: Guiding the Future of Test Automation ( #jassttokai25 , #jassttokai )
teyamagu
PRO
1
240
最近のLinux普段づかいWaylandデスクトップ元年
penguin2716
1
660
Kiro Autonomous AgentとKiro Powers の紹介 / kiro-autonomous-agent-and-powers
tomoki10
0
300
Sansanが実践する Platform EngineeringとSREの協創
sansantech
PRO
2
600
バグハンター視点によるサプライチェーンの脆弱性
scgajge12
3
990
21st ACRi Webinar - Univ of Tokyo Presentation Slide (Ayumi Ohno)
nao_sumikawa
0
120
Reinforcement Fine-tuning 基礎〜実践まで
ch6noota
0
140
エンジニアリングマネージャー はじめての目標設定と評価
halkt
0
250
Playwrightのソースコードに見る、自動テストを自動で書く技術
yusukeiwaki
13
4.7k
プロダクトマネージャーが押さえておくべき、ソフトウェア資産とAIエージェント投資効果 / pmconf2025
i35_267
2
580
非CUDAの悲哀 〜Claude Code と挑んだ image to 3D “Hunyuan3D”を EVO-X2(Ryzen AI Max+395)で動作させるチャレンジ〜
hawkymisc
1
160
グレートファイアウォールを自宅に建てよう
ctes091x
0
140
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Practical Orchestrator
shlominoach
190
11k
What's in a price? How to price your products and services
michaelherold
246
12k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.2k
Navigating Team Friction
lara
191
16k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Code Review Best Practice
trishagee
74
19k
Done Done
chrislema
186
16k
How to Ace a Technical Interview
jacobian
280
24k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
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