Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
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
290
Components on the Web: Frontend NE
jackfranklin
1
850
ReactiveConf: Lessons Migrating Complex Software
jackfranklin
0
540
Front Trends: Migrating complex software
jackfranklin
1
870
Migrating from Angular to React: Manc React
jackfranklin
1
230
Half Stack Fest: Webpack
jackfranklin
4
610
FullStackFest: Elm for JS Developers
jackfranklin
1
280
Codelicious: Intro to ES2015
jackfranklin
0
470
PolyConf: Elm for JS Developers
jackfranklin
0
310
Other Decks in Technology
See All in Technology
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
3
510
空間オーディオで過去の 自分(ゴースト)と競うランニング 〜HealthKitのルートを足音に変える実装〜
nao_randd
0
220
beyond jj: config & tools ecosystem
indirect
0
1k
AI時代、データエンジニアが一番おもろい
genshun9
0
650
アプリをもっと"iOSアプリっぽく"する小さな工夫 / Small Touches That Make Your App Feel More Like an iOS App
matsuji
2
940
[2026-09-11]SREは誰のもの?運用エンジニアが始める 「SRE領域への越境」とチームの進化の軌跡 〜Road to NEXT CRE
tosite
0
290
What the customer really needed
kawaguti
PRO
3
200
AIエージェントの自己改善をどう設計するか / How to Design Self-Improvement for AI Agents
22mi
25
16k
アクセスキーこわい やめかたと漏らさない工夫
sassssan68
1
350
10Xに技術的負債をもたらした「2つの境界の歪み」その構造と解消への営み
10xinc
0
2k
30座EKS, 180次升級淬煉的EKS Upgrade Skill 的歷程
eric8230
0
170
データ界隈LT祭 第1回LT登壇
taromatsui_cccmkhd
2
1.4k
Featured
See All Featured
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
610
Building Applications with DynamoDB
mza
96
7.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
WENDY [Excerpt]
tessaabrams
14
39k
Product Roadmaps are Hard
iamctodd
55
13k
Optimizing for Happiness
mojombo
378
71k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
520
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
We Have a Design System, Now What?
morganepeng
55
8.3k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Navigating Team Friction
lara
192
16k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
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