-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.jade
341 lines (312 loc) · 14.7 KB
/
index.jade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
doctype html
//- basically a copy of the reveal.js html template, reveal content is deleivered from an external source just to simplify the build process of this project
html(lang='en')
head
meta(charset='utf-8')
title The Grunt Task Runner
meta(name='description', content='A talk I gave to the SoME www user group in May, 2014')
meta(name='author', content='Thomas Leen')
meta(name='apple-mobile-web-app-capable', content='yes')
meta(name='apple-mobile-web-app-status-bar-style', content='black-translucent')
meta(name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no')
link(rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/css/reveal.min.css')
link(rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/css/theme/default.css', id='theme')
link(rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/lib/css/zenburn.css')
link(rel='stylesheet' href='index.css')
<!--[if lt IE 9]>
| <script src="//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/lib/js/html5shiv.js"></script>
<![endif]-->
script(src='//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/lib/js/head.min.js')
script(src='//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/js/reveal.min.js')
script(src='//cdnjs.cloudflare.com/ajax/libs/reveal.js/2.6.2/plugin/highlight/highlight.js')
script(src='index.js', defer, async)
body
header
h1 Intro to Grunt
.reveal
.slides
section
img(src='images/grunt-logo.png', alt='The grunt logo')
h2 Grunt
p
| An introduction to the Grunt task runner.
a(href='https://github.com/tleen/somewww-talk-grunt') Built by Grunt
|.
p.credits
| by Tom Leen (tl@thomasleen.com)
section
h2 Grunt is...
ul
li A "task runner"
li Universally seen as a build tool
li Built in Javascript/Node
li Similar tools: Make, Custom scripts (bash...), Rake, Ant, Maven, Phing, Laravel, Gulp...
section
h2 Why use Grunt?
ul
li It is Javascript (one language)
li Lots of pre-made tasks
li Modern orientation in tasks
section
section
h2 Minimal Node
p
| Grunt and its tasks use the
strong: a(href='http://www.nodejs.org') Node environment
| to execute. The end result does not have to be a Node project but the build environment needs to be
i setup
| like one.
section
h2 Project setup
h3 NPM
p
a(href='http://www.npmjs.org') The Node Package Manager
| This will be your means for getting grunt and your needed tasks, NPM gets its information via your...
h3 package.json
p
| You will need a
a(href='https://www.npmjs.org/doc/json.html') package.json
| file to manage your environment. This lives in the root of your project and is a json object of configuration properties.
section
h2 This project's package.json
p The vital part here are the dependencies/devDependencies, this is where grunt and the tasks you need are imported:
pre
code(class='language-javascript')
include ../../package.json
section
h2 NPM install
p Executing the 'npm install' command will cause npm to install all the local dependencies (tasks and support libraries). Then grunt will almost work...
section
h2 grunt-cli
p
| You also need one global command (if you are running on the command line): 'grunt-cli'. The
a(href='https://github.com/gruntjs/grunt-cli') command line runner
| for Grunt.
pre
code(class='language-bash')
| npm install -g grunt-cli
ul
li The 'g' flag installs this globally
li Will run the project local version of grunt
li Solves dependency problems with other projects using different grunt versions
section
section
h2 Gruntfile.js
p
| Grunt looks for its configuration in another file in the root of your project, your
a(href='http://gruntjs.com/sample-gruntfile') Gruntfile.js
|. This file is actually a Node module, that does not have to mean much, except most of your configuration is defined in a
strong Javascript function
| which is passed a grunt object, which is what you actually configure.
section
h2 Task setup
p While NPM gets the tasks, the gruntfile tells Grunt what to do with them.
section
h2 It's Javascript
p The gruntfile is a Javascript file, which means that your Grunt configuration can be programmatically altered. Handy!
section
h2 This project's Grunt.js
pre
code(class='language-javascript')
include ../../Gruntfile.js
section
h2 Three major sections
h3 grunt.initConfig
p Where we configure each task.
h3 grunt.loadNpmTasks
p Where we load each task.
h3 grunt.registerTasks
p Where we setup our task list(s) and ordering
section
section
h2 Tasks
p
| All the things you have Grunt do are called
strong tasks
|, enabled through
strong plugins
|, which are node
strong modules
|.
p All you have to know is that using the package.json file you can install the tasks you need Grunt to use.
section
h2 What do tasks do?
p
| Mostly everything. There are ~2800
a(href='http://gruntjs.com/plugins') available
| at last count.
p Building this presentation we used: S3 upload, directory/file creation/deletion, file concatenation, file copying, CSS|JS|HTML minification, JS|CSS(|HTML) validation, environment manipulation, favicon generation, image optimization, HTML templating, SASS to CSS generation, and automated testing.
p Just for a static website!
section
h2 Configuration
p
| These tasks were
strong already available
| we just had to download and configure them.
section
h2 Tasks in package.json
pre
code(class='language-javascript')
include include/imports-from-package.json
section
h2 Getting tasks
pre
code(class='language-bash')
| npm install
p NPM will take care of finding and installing all the tasks listed in your package.json file (and the proper versions too!)
section
h2 Loading tasks
p You load the tasks in your Gruntfile:
pre
code(class='language-javascript')
include include/gruntfile-load-tasks.js
p Now they are available for use...
section
h2 Registering tasks
p You can setup lists of tasks to run, sometimes you only want to run a few, other time more.
pre
code(class='language-javascript')
include include/gruntfile-register-tasks.js
p You need to call "registerTask" with an array of task names in order of execution.
section
h2 Task Names
p
| Tasks come with a default name, look in each tasks doc, its usually the last part of the task plugin's name. For example 'grunt-contrib-
strong copy
| is referenced as 'copy'. This is not always the case, see each plugin's docs. This is the name you use in the task list.
section
h2 Array of task names
p Because the task list is an array, and the Gruntfile is Javascript you can also programatically maniplate it:
pre
code(class='language-javascript')
include include/gruntfile-update-tasks.js
p Rather than list my tasks twice, I just add my 'publish' tasks to the end of the list.
section
h2 Default tasks
p When you register a task list with the name 'default' that task list will execute if you call grunt without specifying a list:
pre
code(class='language-bash')
| grunt
section
h2 More task lists
p You can run other lists of tasks by using a name that is not 'default', and calling grunt with that name as the argument. In this project there are two defined task lists:
h3 default
p Build project to a local destination
pre
code(class='language-bash')
| grunt
h3 publish
p Build project to a local destination and upload to s3
pre
code(class='language-bash')
| grunt publish
section
h2 Task targets
p Some tasks are called by name alone, others are called by name, with a following ':' and a further description.
pre
code(class='language-javascript')
include include/gruntfile-register-tasks-sub.js
p These are different configurations of the same task. This lets you use a task differently in the same list.
section
section
h2 Configuration
p Most of the work in setting up Grunt will be in your task configuration. This takes place in the grunt.initConfig function:
pre
code(class='language-javascript')
include include/gruntfile-init-config.js
section
h2 Main concepts
p Grunt tasks are configured around three main concepts:
h3 Targets
p A specific named configuration
h3 Files
p What files to operate on (and where to write results)
h3 Options
p Task dependent options for how it should run
section
h2 Simple config example
pre
code(class='language-javascript')
include include/single-task-config.js
p A very simple task configuration for the "uglify" task. Take in the "tmp/index.js" file as input, uglify and output as the same file.
section
h2 Targets
p You can name the specific configurations, so that you may call that configuration. Remember the ':'? You don't have to name it if you just want to run that one configuration simply.
pre
code(class='language-javascript')
include include/gruntfile-task-targets.js
pre
code(class='language-bash')
| grunt concat # run the js and css (all) tasks
| grunt concat:js # just run the one named task configuration
section
h2 Target names
p The names are descriptive, but dont have to be anything specific.
p
| except "
strong options
|" that is reserved for setting up the options for each task...
section
h2 Options
p You can pass these in under the property name "options":
pre
code(class='language-javascript')
include include/options.js
p If options are at the same level as the targets these options apply to all task targets, you can override locally in the target configuration.
section
h2 Which Options
p The options are dependent on each task, use the documentation for each to figure out what to use and why.
section
section
h2 File configurations
p
| Because file input and output is so often used in Grunt tasks, Grunt has a
a(href='http://gruntjs.com/configuring-tasks') sophisticated syntax
| for describing file locations and sources (src-dest mappings).
p Wildcards, directory expansion, even using javascript functions to filter files. Very flexible!
section
h2 File configurations :(
p There are also a lot of ways to configure files. It can get confusing. Use their docs:
ul
li: a(href='http://gruntjs.com/configuring-tasks#compact-format') Compact Format
li: a(href='http://gruntjs.com/configuring-tasks#files-object-format') Files Object Format
li: a(href='http://gruntjs.com/configuring-tasks#files-array-format') Files Array Format
section
h2 File selection globbing
p
| This is where you can do a lot with the built in
a(href='http://gruntjs.com/configuring-tasks#globbing-patterns') pattern matching
|:
pre
code(class='language-javascript')
include include/globbing.js
section
h2 Expanding
p
| Most useful is building the files object dynamically
a(href='http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically') via expanding
|:
pre
code(class='language-javascript')
include include/expanding.js
p
| This has Grunt finding the input files via the pattern
strong and
| creating the output file pattern based on the input file. Handy!
section
section
h2 Passing data
p Another useful thing you can do is pass data into tasks. This lets you store things like credentials securely. You can then pass these into options.
section
h2 Example
pre
code(class='language-javascript')
include include/grunt-passing-data.js
section
h2 Tests
p
| You can see in the tests that I use data passing and
a(href='https://github.com/jsoverson/grunt-env') grunt-env
| to test that things were properly built and placed.
//
Generated @ #{datetime}, version #{version}