Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Grunt your way to Glory - SideView 2013
Search
Shaun D
November 09, 2013
Technology
3
270
Grunt your way to Glory - SideView 2013
Presentation from SideView 2013 - Grunt you way to Glory
Shaun D
November 09, 2013
Tweet
Share
More Decks by Shaun D
See All by Shaun D
The Open Metaverse - Front End Kent
shaunix
0
62
The Open Metaverse - Reactivate London
shaunix
1
83
The Open Metaverse - Fullstack Bytes
shaunix
0
130
In Your Face : WebVR
shaunix
0
100
This is for Everyone
shaunix
0
670
A11Y & React : This is for Everyone
shaunix
1
180
Make Mine Meteor - Real Time Applications, Hyperspeed Time
shaunix
1
90
Grunt your way to Glory : LDNJS - 15th July 2013
shaunix
3
170
Grunt you way to Glory : LNUG MAY
shaunix
4
330
Other Decks in Technology
See All in Technology
オープンデータの内製化から分かったGISデータを巡る行政の課題
naokim84
2
1.4k
M5UnifiedとPicoRubyで楽しむM5シリーズ
kishima
0
120
私のRails開発環境
yahonda
0
180
セキュリティAIエージェントの現在と未来 / PSS #2 Takumi Session
flatt_security
3
1.4k
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
9.9k
eBPFとwaruiBPF
sat
PRO
4
1.9k
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
980
Eight Engineering Unit 紹介資料
sansan33
PRO
0
5.8k
Playwrightのソースコードに見る、自動テストを自動で書く技術
yusukeiwaki
9
3.4k
生成AI・AIエージェント時代、データサイエンティストは何をする人なのか?そして、今学生であるあなたは何を学ぶべきか?
kuri8ive
2
1.9k
なぜ使われないのか?──定量×定性で見極める本当のボトルネック
kakehashi
PRO
1
820
Ryzen NPUにおけるAI Engineプログラミング
anjn
0
230
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
Building an army of robots
kneath
306
46k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.4k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
960
It's Worth the Effort
3n
187
29k
GitHub's CSS Performance
jonrohan
1032
470k
The Invisible Side of Design
smashingmag
302
51k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
380
Transcript
GRUNT YOUR GRUNT YOUR WAY TO GLORY WAY TO GLORY
or:how to stop doing things manually and learn to love automation
Automation isn’t about being lazy. It’s about being efficient. -
Addy Osmani
ENSIGN DEV
UGLYFY&MINFY COMPILE&CONCAT COMPRESS&OPTIMISE IMAGES LINT JS BLESS CSS GENERATE DOCUMENTATION
STICK IT IN BUILD ZIP IT&UPLOAD IT TO S3
#!/bin/sh
MAKE RAKE CAKE JAKE
MAKE RAKE CAKE JAKE
MAKE RAKE CAKE JAKE
@paul_irish
None
<target name="jshint">! <apply dir="${dir.source}/${dir.js}" executable="java" parallel="false" failonerror="true">! <fileset dir="./${dir.source}/">! <include
name="**/${dir.js}/*.js"/>! <exclude name="**/*.min.js"/>! <exclude name="${dir.intermediate}/**/*.js"/>! <exclude name="**/${dir.js.libs}/"/>! <exclude name="**/${dir.publish}/"/>! </fileset>! <arg value="-jar" />! <arg path="./${dir.build.tools}/${tool.rhino}" />! <arg path="./${dir.build.tools}/${tool.jshint}" />! <srcfile/>! <arg value="${tool.jshint.opts}" />! </apply>! <echo>JSHint Successful</echo>! </target>!
<target name="jshint">! <apply dir="${dir.source}/${dir.js}" executable="java" parallel="false" failonerror="true">! <fileset dir="./${dir.source}/">! <include
name="**/${dir.js}/*.js"/>! <exclude name="**/*.min.js"/>! <exclude name="${dir.intermediate}/**/*.js"/>! <exclude name="**/${dir.js.libs}/"/>! <exclude name="**/${dir.publish}/"/>! </fileset>! <arg value="-jar" />! <arg path="./${dir.build.tools}/${tool.rhino}" />! <arg path="./${dir.build.tools}/${tool.jshint}" />! <srcfile/>! <arg value="${tool.jshint.opts}" />! </apply>! <echo>JSHint Successful</echo>! </target>!
CODEKIT PREPROS HAMMERforMAC LIVERELOAD MIXTURE £ £ £ £ free
None
None
None
None
{! "name": "new-project",! "version": "0.0.1" }
{! "name": "new-project",! "version": "0.0.1" }
"devDependencies": {! "grunt": "~0.4.1"! } , {! "name": "new-project",! "version":
"0.0.1" ! }
Shell functions. Make it so! .bashrc / .zshrc function gi(){!
! npm install --save-dev grunt-"$@"! }! ! function gci(){! ! npm install --save-dev grunt-contrib-"$@"! }!
None
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { );
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { ); grunt.loadNpmTasks('grunt-contrib-jshint');
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { ); grunt.loadNpmTasks('grunt-contrib-jshint');
jshint: {! options: { jshintrc: '.jshintrc' },! all: ['**/*.js']! }
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { ); grunt.loadNpmTasks('grunt-contrib-jshint');
jshint: {! options: { jshintrc: '.jshintrc' },! all: ['**/*.js']! } {! "bitwise": true,! "camelcase": true,! "curly": true,! "eqeqeq": true,! "forin": true,! "immed": true,! "indent": 4,! "browser": true,! "jquery": true,! "white": false! }
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { ); grunt.loadNpmTasks('grunt-contrib-jshint');
jshint: {! options: { jshintrc: '.jshintrc' },! all: ['**/*.js']! } {! "bitwise": true,! "camelcase": true,! "curly": true,! "eqeqeq": true,! "forin": true,! "immed": true,! "indent": 4,! "browser": true,! "jquery": true,! "white": false! } , ['jshint'] task name task list
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { ); grunt.loadNpmTasks('grunt-contrib-jshint');
jshint: {! options: { jshintrc: '.jshintrc' },! all: ['**/*.js']! } , ['jshint' ] grunt.loadNpmTasks('grunt-contrib-uglify'); uglify: {! options: { compress: { unsafe: false } },! dist: {! options: {! banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +! '<%= grunt.template.today("yyyy-mm-dd") %> */\n',! }, ! src: '<%= scripts %>',! dest: paths.min! } , ,'uglify'
}; grunt }); module grunt jshint options all } grunt
uglify: {! options: { compress: { unsafe: false } },! dist: {! options: {! banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +! '<%= grunt.template.today("yyyy-mm-dd") %> */\n',! }, ! src: '<%= scripts %>',! dest: paths.min! } , var pkg = grunt.file.readJSON('package.json'); var scripts = ['assets/**/*.js', '!**/*.min.js'] grunt.registerTask('default' ); , ['jshint' ] ,'uglify'
Globbing! Make it so! var scripts = ['assets/**/*.js', '!**/*.min.js'] all
.js files INC sub directories ! negates the pattern match more : https://github.com/cowboy/node-globule
}; grunt }); module grunt.loadNpmTasks('grunt-contrib-jshint'); jshint options all } grunt.loadNpmTasks('grunt-contrib-uglify');
uglify options dist }, ! } , grunt.registerTask('default' ); , ['jshint' ] ,'uglify'
matchdep. Make it so! require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
}; grunt.initConfig({ }); grunt.registerTask('default' module.exports = function(grunt) { ); jshint:
{! options: { jshintrc: '.jshintrc' },! all: ['**/*.js']! } , ['jshint'] uglify: {! options: { compress: { unsafe: false } },! dist: {! options: {! banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +! '<%= grunt.template.today("yyyy-mm-dd") %> */\n',! }, ! src: '<%= scripts %>',! dest: paths.min! } , require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
None
configGrunt = function (grunt) { ! ! var taskConfig =
{! /* ALL THE GRUNT TASK CONFIGURATION */! }! ! grunt.initConfig(taskConfig);! ! grunt.registerTask('default', ['jshint', 'uglify', 'concat']});! grunt.registerTask('build', ['jshint', 'uglify', 'concat', 'S3', 'groc']});! ! }! ! module.exports = configGrunt;
YOU’RE GONNA SEE SOME SERIOUS S**T
50,000 +
1000+
None
+
Sass LESS CoffeeScript TypeScript Jade markdown
None
None
None
None
None
npm install -g grunt-init git clone https://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin grunt-init TEMPLATENAME
None
None
None
None
CONFIG {or} SCRIPT CONSISTENT COMMUNITY POWERFUL
USE <3 AUTOMATION PEEK @ GRUNTFILES CONTRIBUTE
niceagency.co.uk
SHAUN DUNNE SHAUN DUNNE @shaundunne || +shaundunne || github.com/shaundune www.shaundunne.com