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
Giving your Development more Grunt - FOWA Londo...
Search
Jack Franklin
October 25, 2013
Technology
670
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Giving your Development more Grunt - FOWA London 2013
An in-depth introduction to GruntJS and some of the best plugins available.
Jack Franklin
October 25, 2013
More Decks by Jack Franklin
See All by Jack Franklin
Advanced React Meetup: Testing JavaScript
jackfranklin
1
270
Components on the Web: Frontend NE
jackfranklin
1
850
ReactiveConf: Lessons Migrating Complex Software
jackfranklin
0
520
Front Trends: Migrating complex software
jackfranklin
1
850
Migrating from Angular to React: Manc React
jackfranklin
1
210
Half Stack Fest: Webpack
jackfranklin
4
600
FullStackFest: Elm for JS Developers
jackfranklin
1
270
Codelicious: Intro to ES2015
jackfranklin
0
450
PolyConf: Elm for JS Developers
jackfranklin
0
300
Other Decks in Technology
See All in Technology
[チョークトーク資料]AWS DevOps Agent を使いこなす / AWS Dev Ops Agent Chalk Talk AWS Summit Japan 2026
kinunori
1
370
あなたの知らないPDFのアクセシビリティ
lycorptech_jp
PRO
0
210
iAEONの段階的リアーキテクト戦略 / iAEON's_Gradual_Re-architecture_Strategy
aeonpeople
0
220
AWS Security Agent といっしょに脅威モデリングをやってみよう
amarelo_n24
0
130
自律型AIエージェントは何を破壊するのか
kojira
0
160
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
0
2.4k
AmazonRoute 53ではじめてのドメイン取得!HTTPS化までの道のりを整理してみた
usanchuu
3
150
SONiCで構築・運用する生成AI向けパブリッククラウドネットワーク ~実装編~
sonic
0
250
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
1.2k
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
270
AI駆動開発を通して感じた、 AI時代のデザイナーの役割変化
whisaiyo
3
2.2k
作って終わりにしない タイミーのセマンティックレイヤー育成の現在地
chanyou0311
4
2.4k
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
200
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
390
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
250
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
440
Discover your Explorer Soul
emna__ayadi
2
1.1k
For a Future-Friendly Web
brad_frost
183
10k
Odyssey Design
rkendrick25
PRO
2
700
Heart Work Chapter 1 - Part 1
lfama
PRO
7
36k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
Embracing the Ebb and Flow
colly
88
5.1k
Transcript
GIVING YOUR DEVELOPMENT MORE GRUNT @jack_franklin #FOWA
comp-sci student javascript / ruby author & blogger
THANKS ADDY!
None
0.4.1
PLUGINS
NODE
npm
WINDOWS
npm install grunt-cli -g installing grunt the package to install
install it globally (system wide)
mkdir my-new-project cd my-new-project new project
{ "name": "my-sample-app", "version": "0.0.0", "devDependencies": { "grunt": "0.4.1" }
} package.json
install deps npm install
module.exports = function(grunt) { grunt.initConfig({ // config goes here });
}; Gruntfile.js
Gruntfile.js package.json src/ - one.js - two.js - three.js src
files
npm install grunt-contrib-uglify --save-dev uglify plugin
{ ... "devDependencies": { "grunt": "0.4.1", "grunt-contrib-uglify": "~0.2.4" } }
package.json
module.exports = function(grunt) { grunt.initConfig({ // config goes here });
grunt.loadNpmTasks(“grunt- contrib-uglify”); }; Gruntfile.js
module.exports = function(grunt) { grunt.initConfig({ uglify: { minify: { files:
{ 'dist/out.js': ['src/*.js'] } } } }); ... }; Gruntfile.js
> grunt uglify Running "uglify:minify" (uglify) task File "dist/out.js" created.
Done, without errors. Running the task
grunt.loadNpmTasks(...); grunt.registerTask(“default”, “uglify”); Gruntfile.js > grunt # now runs the
uglify task
npm install grunt-contrib-jshint --save-dev JSHint
grunt.loadNpmTasks(“grunt-contrib- uglify”); grunt.loadNpmTasks(“grunt-contrib- jshint”); Gruntfile.js
uglify: { /* snip */ }, jshint: { all: ['Gruntfile.js',
'src/ *.js'] }, // rest of Gruntfile Gruntfile.js
> grunt jshint Running "jshint:all" (jshint) task >> 4 files
lint free. Done, without errors. Running the task
grunt.registerTask(“default”, [“jshint”, “uglify”]); Default Task
> grunt Running "jshint:all" (jshint) task >> 4 files lint
free. Running "uglify:minify" (uglify) task File "dist/out.js" created. Done, without errors. Running grunt
// JSHint won't like the missing // semi colon console.log("file
2") src/two.js
Running "jshint:all" (jshint) task Linting src/two.js ...ERROR [L2:C22] W033: Missing
semicolon. console.log("file 2") Warning: Task "jshint:all" failed. Use --force to continue. Aborted due to warnings. Running grunt
Multi Tasks lots of tasks can have different configurations
module.exports = function(grunt) { grunt.initConfig({ uglify: { minify: { files:
{ 'dist/out.js': ['src/*.js'] } } } }); ... }; Gruntfile.js
uglify: { minify: { /* snip */ }, withBanner: {
options: { banner: "/*Hello World*/" }, files: { 'dist/out.js': ['src/*.js'] } } }, // rest of Gruntfile Gruntfile.js
> grunt uglify:withBanner Running "uglify:withBanner" (uglify) task File "dist/out.js" created.
Done, without errors. Running a task
> cat dist/out.js /*Hello World*/console.log("file 1"),console.log("file 3"),console.log("file 2"); Gruntfile.js
grunt.registerTask("default", ["jshint", "uglify:withBanner"]); Gruntfile.js
npm install grunt-contrib-watch --save-dev Watching
grunt.loadNpmTasks('grunt-contrib-watch'); Watching
uglify: { /*snip*/ }, watch: { files: [‘src/*.js’, ‘Gruntfile.js’], tasks:
[‘jshint’], }, jshint: { /*snip*/ } Gruntfile.js
> grunt watch Running "watch" task Waiting...OK >> File "src/two.js"
changed. Running "jshint:all" (jshint) task >> 4 files lint free. Done, without errors. Completed in 0.470s at Wed Oct 23 2013 14:27:08 GMT+0100 (BST) - Waiting... Watching
Watching Running JSHint constantly Checking tests haven’t broken Auto compiling
Sass/Less
Notifications npm install grunt-notify --save-dev grunt.loadNpmTasks('grunt-contrib-notify');
None
Testing npm install grunt-contrib-jasmine --save- dev grunt.loadNpmTasks('grunt-contrib- jasmine');
Gruntfile.js jshint: { /* snip */ }, jasmine: { test:
{ src: 'src/*.js', options: { specs: 'spec/*.js' } } }, watch: { /*snip */ },
spec/test.js describe("my app", function() { it("passes", function() { expect(two()).toEqual(2); });
});
src/two.js window.two = function() { return 2; };
Testing > grunt jasmine Running "jasmine:test" (jasmine) task Testing jasmine
specs via phantom . 1 spec in 0.001s. >> 0 failures Done, without errors.
Default Task grunt.registerTask("default", [ "jshint", "jasmine", "uglify:withBanner" ]);
Default Task Running "jshint:all" (jshint) task >> 4 files lint
free. Running "jasmine:test" (jasmine) task Testing jasmine specs via phantom . 1 spec in 0.002s. >> 0 failures Running "uglify:withBanner" (uglify) task File "dist/out.js" created. Done, without errors.
Errors Running "jshint:all" (jshint) task >> 4 files lint free.
Running "jasmine:test" (jasmine) task Testing jasmine specs via phantom x my app:: passes: failed Expected 2 to equal 3. (1) 1 spec in 0.002s. >> 1 failures
npm install grunt-concurrent --save-dev grunt.loadNpmTasks('grunt-concurrent'); Concurrent
concurrent: { target1: ['jasmine', 'jshint'] } grunt.registerTask("default", [ "concurrent:target1", "uglify:withBanner"
]); Gruntfile.js
Running "concurrent:target1" (concurrent) task Running "jshint:all" (jshint) task >> 4
files lint free. Done, without errors. Running "jasmine:test" (jasmine) task Testing jasmine specs via phantom 1 spec in 0.001s. >> 0 failures Done, without errors. Running "uglify:withBanner" (uglify) task File "dist/out.js" created. Done, without errors.
None
"src/*.js" Tidying Up
grunt.initConfig({ srcFiles: "src/*.js", uglify: { /*snip */ }, ... });
Defining Vars
jshint: { all: [ 'Gruntfile.js', '<%= srcFiles %>' ] },
Using Vars
define once refer lots change once
grunt.initConfig({ srcFiles: "src/*.js", outFile: "dist/out.js", uglify: { /* snip */
}, ... }); More Vars
minify: { files: { '<%= outFile %>': ['<%= srcFiles %>']
} } More Vars
grunt.loadNpmTasks("grunt-contrib- uglify"); grunt.loadNpmTasks("grunt-contrib- jshint"); grunt.loadNpmTasks("grunt-contrib- watch"); grunt.loadNpmTasks("grunt-contrib- jasmine"); grunt.loadNpmTasks("grunt- notify");
Match Dep
npm install matchdep --save-dev Match Dep
// replace all the loadNpmTask() lines with: require('matchdep') .filterDev('grunt-*') .forEach(grunt.loadNpmTasks);
Match Dep
“work less, do more, make awesome” -@addyosmani
be lazy automate lessen friction
“embrace the ecosystem” -me, Generate Conf, Sept 2013
love your tools get to know them
None
setup once use again and again iterate
scratched the surface
popular jQuery BBC Twitter Adobe Bocoup Opera WordPress
700+ plugins http://gruntjs.com/plugins
700+ plugins minification image optimisation templating compiling local servers live
reloading
for more gruntjs.com @gruntjs @gruntweekly #grunt on freenode
be warned! watch out for outdated tutorials
0.4.1
any (easy) questions? speakerdeck.com/jackfranklin @jack_franklin javascriptplayground.com https://github.com/javascript-playground/fowa-grunt-talk