Más contenido relacionado La actualidad más candente (20) Similar a Dethroning Grunt: Simple and Effective Builds with gulp.js (20) Dethroning Grunt: Simple and Effective Builds with gulp.js4. that is a lot of things to do
task runners simplify to one command
8. //
Project
Specific
Tasks
grunt.loadNpmTasks('grunt-‐bower-‐task');
grunt.loadNpmTasks('grunt-‐coffeelint');
grunt.loadNpmTasks('grunt-‐contrib-‐clean');
grunt.loadNpmTasks('grunt-‐contrib-‐coffee');
grunt.loadNpmTasks('grunt-‐contrib-‐concat');
grunt.loadNpmTasks('grunt-‐contrib-‐connect');
grunt.loadNpmTasks('grunt-‐contrib-‐copy');
grunt.loadNpmTasks('grunt-‐contrib-‐cssmin');
grunt.loadNpmTasks('grunt-‐contrib-‐jade');
grunt.loadNpmTasks('grunt-‐contrib-‐jshint');
grunt.loadNpmTasks('grunt-‐contrib-‐less');
grunt.loadNpmTasks('grunt-‐contrib-‐uglify');
grunt.loadNpmTasks('grunt-‐contrib-‐watch');
10. //
13
tasks
in
all
grunt.loadNpmTasks('grunt-‐bower-‐task');
grunt.loadNpmTasks('grunt-‐coffeelint');
grunt.loadNpmTasks('grunt-‐contrib-‐clean');
grunt.loadNpmTasks('grunt-‐contrib-‐coffee');
grunt.loadNpmTasks('grunt-‐contrib-‐concat');
grunt.loadNpmTasks('grunt-‐contrib-‐connect');
grunt.loadNpmTasks('grunt-‐contrib-‐copy');
grunt.loadNpmTasks('grunt-‐contrib-‐cssmin');
grunt.loadNpmTasks('grunt-‐contrib-‐jade');
grunt.loadNpmTasks('grunt-‐contrib-‐jshint');
grunt.loadNpmTasks('grunt-‐contrib-‐less');
grunt.loadNpmTasks('grunt-‐contrib-‐uglify');
grunt.loadNpmTasks('grunt-‐contrib-‐watch');
11. gruntfile.coffee
timer
=
require
"grunt-‐timer"
fs
=
require
'fs'
path
=
require
'path'
server
=
require
'./config/server'
urlrouter
=
require
'urlrouter'
module.exports
=
(grunt)
-‐>
timer.init
grunt
#
Project
configuration.
grunt.initConfig
pkg:
grunt.file.readJSON
'package.json'
files:
coffee:
app:
"app/js/**/*.coffee"
generated:
"generated/js/app.coffee.js"
css:
vendor:
"vendor/css/**/*.css"
app:
"app/css/**/*.css"
concatenated:
"generated/css/app.css"
minified:
"dist/css/app.css"
minifiedWebRelative:
"css/app.css"
img:
root:
"img"
jade:
pages:
"**/*.jade"
pageRoot:
"app/pages/"
js:
app:
"app/js/**/*.js"
vendor:
[
"vendor/components/jquery/jquery.js"
"vendor/components/underscore/underscore.js"
"vendor/components/angular/angular.js"
"vendor/js/**/*.js"
]
concatenatedVendor:
"generated/js/vendor.js"
minifiedVendor:
"dist/js/vendor.js"
minifiedVendorWebRelative:
"js/vendor.js"
concatenated:
"generated/js/app.js"
minified:
"dist/js/app.js"
minifiedWebRelative:
"js/app.js"
less:
app:
"app/css/app.less"
vendor:
"vendor/css/**/*.less"
generatedApp:
"generated/css/app.less.css"
generatedVendor:
"generated/css/vendor.less.css"
watch:
"app/css/**/*.less"
webfonts:
root:
"fonts"
bower:
install:
options:
copy:
false
coffee:
compile:
files:
"<%=
files.coffee.generated
%>":
"<%=
files.coffee.app
%>"
coffeelint:
app:
[
"<%=
files.coffee.app
%>"
]
concat:
css:
src:
[
"<%=
files.less.generatedVendor
%>"
"<%=
files.css.vendor
%>"
"<%=
files.less.generatedApp
%>"
"<%=
files.css.app
%>"
]
dest:
"<%=
files.css.concatenated
%>"
js:
src:
[
"<%=
files.coffee.generated
%>"
"<%=
files.js.app
%>"
]
dest:
"<%=
files.js.concatenated
%>"
jsVendor:
src:
["<%=
files.js.vendor
%>"]
dest:
"<%=
files.js.concatenatedVendor
%>"
connect:
server:
options:
port:
8000
base:
'generated'
open:
true
middleware:
(connect,
options)
-‐>
middlewares
=
[];
if
(!Array.isArray(options.base))
options.base
=
[options.base]
directory
=
options.directory
||
options.base[options.base.length
-‐
1]
options.base.forEach
(base)
-‐>
#
Serve
static
files.
middlewares.push(connect.static(base))
middlewares.push
urlrouter(server.drawRoutes)
#
Make
directory
browse-‐able.
middlewares.push
connect.directory(directory)
middlewares
copy:
imagesDev:
files:
[{
expand:
true
cwd:
"app/img/"
src:
"**"
dest:
"generated/<%=
files.img.root
%>/"
}
{
expand:
true
cwd:
"vendor/img/"
src:
"**"
dest:
"generated/<%=
files.img.root
%>/"
}]
imagesDist:
files:
[{
expand:
true
cwd:
"app/img/"
src:
"**"
dest:
"dist/<%=
files.img.root
%>/"
}
{
expand:
true
cwd:
"vendor/img/"
src:
"**"
dest:
"dist/<%=
files.img.root
%>/"
}]
staticDev:
files:
[
expand:
true
cwd:
"app/static"
src:
"**"
dest:
'generated'
]
staticDist:
files:
[
expand:
true
cwd:
"app/static"
src:
"**"
dest:
'dist'
]
webfontsDev:
files:
[{
expand:
true
cwd:
"vendor/webfonts/"
src:
"**"
dest:
"generated/<%=
files.webfonts.root
%>/"
}
{
expand:
true
cwd:
"vendor/components/font-‐awesome/fonts/"
src:
"**"
dest:
"generated/<%=
files.webfonts.root
%>/"
}]
webfontsDist:
files:
[{
expand:
true
cwd:
"vendor/webfonts/"
src:
"**"
dest:
"dist/<%=
files.webfonts.root
%>/"
}
{
expand:
true
cwd:
"vendor/components/font-‐awesome/fonts/"
src:
"**"
dest:
"dist/<%=
files.webfonts.root
%>/"
}]
cssmin:
compress:
files:
"<%=
files.css.minified
%>":
"<%=
files.css.concatenated
%>"
css:
files:
["<%=
files.css.vendor
%>",
"<%=
files.css.app
%>"]
tasks:
["concat:css"]
jade:
dev:
options:
pretty:
true
data:
js:
"<%=
files.js.minifiedWebRelative
%>"
jsVendor:
"<%=
files.js.minifiedVendorWebRelative
%>"
css:
"<%=
files.css.minifiedWebRelative
%>"
pkg:
"<%=
pkg
%>"
files:
[{
expand:
true
src:
"<%=
files.jade.pages
%>"
cwd:
"<%=
files.jade.pageRoot
%>"
dest:
"generated/"
ext:
".html"
}]
dist:
options:
data:
js:
"<%=
minifiedWebRelative
%>"
jsVendor:
"<%=
minifiedVendorWebRelative
%>"
css:
"<%=
files.css.minifiedWebRelative
%>"
pkg:
"<%=
pkg
%>"
files:
[{
expand:
true
src:
"<%=
files.jade.pages
%>"
cwd:
"<%=
files.jade.pageRoot
%>"
dest:
"dist/"
ext:
".html"
}]
js:
files:
["<%=
files.js.vendor
%>",
"<%=
files.js.app
%>"]
tasks:
["concat:js"]
jshint:
files:
["<%=
files.js.app
%>"]
options:
#
enforcing
options
curly:
true
eqeqeq:
true
latedef:
true
newcap:
true
noarg:
true
#
relaxing
options
boss:
true
eqnull:
true
sub:
true
#
environment/globals
browser:
true
less:
options:
paths:
["app/css",
"vendor/css"]
compile:
files:
"<%=
files.less.generatedVendor
%>":
"<%=
files.less.vendor
%>"
"<%=
files.less.generatedApp
%>":
"<%=
files.less.app
%>"
uglify:
options:
banner:
'/*!
<%=
pkg.name
%>
<%=
grunt.template.today("yyyy-‐mm-‐dd")
%>
*/n'
js:
files:
"<%=
files.js.minified
%>":
"<%=
files.js.concatenated
%>"
jsVendor:
files:
"<%=
files.js.minifiedVendor
%>":
"<%=
files.js.concatenatedVendor
%>"
clean:
bower:
src:
bowerDirectory
grunt
js:
src:
"<%=
files.js.concatenated
%>"
css:
src:
"<%=
files.css.concatenated
%>"
dist:
src:
["dist",
"generated"]
watch:
coffee:
files:
"<%=
files.coffee.app
%>"
tasks:
["coffeelint",
"coffee",
"concat:js"]
images:
files:
["app/img/**/*.*",
"vendor/img/**/*.*"]
tasks:
["copy:imagesDev"]
jade:
files:
["<%=
files.jade.pageRoot
%>/<%=
files.jade.pages
%>"]
tasks:
["jade:dev"]
less:
files:
[
"<%=
files.less.vendor
%>"
"<%=
files.less.watch
%>"
]
tasks:
["less",
"concat:css"]
lint:
files:
"<%=
files.js.app
%>"
tasks:
["jshint"]
webfonts:
files:
["vendor/webfonts/**/*.*",
"vendor/components/font-‐awesome/fonts/**/*.*"]
tasks:
["copy:webfontsDev"]
livereload:
options:
livereload:
true
files:
"dist/**/*.*"
grunt.loadNpmTasks
'grunt-‐bower-‐task'
grunt.loadNpmTasks
'grunt-‐coffeelint'
grunt.loadNpmTasks
'grunt-‐contrib-‐clean'
grunt.loadNpmTasks
'grunt-‐contrib-‐coffee'
grunt.loadNpmTasks
'grunt-‐contrib-‐concat'
grunt.loadNpmTasks
'grunt-‐contrib-‐connect'
grunt.loadNpmTasks
'grunt-‐contrib-‐copy'
grunt.loadNpmTasks
'grunt-‐contrib-‐cssmin'
grunt.loadNpmTasks
'grunt-‐contrib-‐jshint'
grunt.loadNpmTasks
'grunt-‐contrib-‐less'
grunt.loadNpmTasks
'grunt-‐contrib-‐jade'
grunt.loadNpmTasks
'grunt-‐contrib-‐uglify'
grunt.loadNpmTasks
'grunt-‐contrib-‐watch'
grunt.registerTask
'default',
[
'common'
'dev'
]
grunt.registerTask
'common',
[
'bower'
'coffeelint'
'jshint'
'coffee'
'less'
'concat'
'copy:staticDev'
'copy:imagesDev'
'copy:webfontsDev'
'jade:dev'
]
grunt.registerTask
'dev',
[
'connect'
'watch'
]
grunt.registerTask
'dist',
[
'uglify'
'cssmin'
'copy:staticDist'
'copy:imagesDist'
'copy:webfontsDist'
'jade:dist'
]
bowerDirectory
=
(grunt)
-‐>
bowerrc
=
path.join(process.cwd(),
".bowerrc")
bowerConfig
=
grunt.file.readJSON(bowerrc)
unless
!fs.existsSync(bowerrc)
bowerConfig?.directory
||
"vendor/components"
12. ├──
css
│
├──
app.less
│
├──
mixins.less
│
└──
variables.less
├──
img
│
├──
arana-‐software.png
│
├──
arana-‐software@2x.png
│
├──
banner-‐lg.png
│
├──
banner-‐md.png
│
├──
banner-‐sm.png
│
├──
crown.png
│
├──
leather@1x.jpg
│
├──
leather@2x.jpg
│
└──
wood.png
├──
js
│
├──
app.coffee
│
├──
controllers
│
│
└──
board.coffee
│
├──
directives
│
│
└──
board.js
│
└──
templates
│
└──
board.coffee
├──
pages
│
└──
index.jade
└──
static
└──
favicon.ico
gruntfile.coffee
timer
=
require
"grunt-‐timer"
fs
=
require
'fs'
path
=
require
'path'
server
=
require
'./config/server'
urlrouter
=
require
'urlrouter'
jsVendor:
src:
["<%=
files.js.vendor
%>"]
dest:
"<%=
files.js.concatenatedVendor
%>"
{
css:
expand:
true
files:
["<%=
files.css.vendor
%>",
"<%=
files.css.app
%>"]
cwd:
"vendor/components/font-‐awesome/fonts/"
tasks:
["concat:css"]
src:
"**"
dest:
"dist/<%=
files.webfonts.root
%>/"
images:
}]
files:
["app/img/**/*.*",
"vendor/img/**/*.*"]
tasks:
["copy:imagesDev"]
cssmin:
compress:
jade:
files:
files:
["<%=
files.jade.pageRoot
%>/<%=
files.jade.pages
%>"]
"<%=
files.css.minified
%>":
"<%=
files.css.concatenated
%>"
tasks:
["jade:dev"]
connect:
server:
module.exports
=
(grunt)
-‐>
options:
timer.init
grunt
port:
8000
base:
'generated'
#
Project
configuration.
open:
true
grunt.initConfig
middleware:
(connect,
options)
-‐>
pkg:
grunt.file.readJSON
'package.json'
middlewares
=
[];
if
(!Array.isArray(options.base))
jade:
js:
files:
options.base
=
[options.base]
dev:
files:
["<%=
files.js.vendor
%>",
"<%=
files.js.app
%>"]
coffee:
options:
tasks:
["concat:js"]
app:
"app/js/**/*.coffee"
directory
=
options.directory
||
options.base[options.base.length
-‐
1]
pretty:
true
generated:
"generated/js/app.coffee.js"
options.base.forEach
(base)
-‐>
data:
less:
#
Serve
static
files.
js:
"<%=
files.js.minifiedWebRelative
%>"
files:
[
css:
middlewares.push(connect.static(base))
jsVendor:
"<%=
files.js.minifiedVendorWebRelative
%>"
"<%=
files.less.vendor
%>"
vendor:
"vendor/css/**/*.css"
css:
"<%=
files.css.minifiedWebRelative
%>"
"<%=
files.less.watch
%>"
app:
"app/css/**/*.css"
middlewares.push
urlrouter(server.drawRoutes)
pkg:
"<%=
pkg
%>"
]
concatenated:
"generated/css/app.css"
#
Make
directory
browse-‐able.
files:
[{
tasks:
["less",
"concat:css"]
minified:
"dist/css/app.css"
middlewares.push
connect.directory(directory)
expand:
true
minifiedWebRelative:
"css/app.css"
middlewares
src:
"<%=
files.jade.pages
%>"
lint:
cwd:
"<%=
files.jade.pageRoot
%>"
files:
"<%=
files.js.app
%>"
img:
copy:
dest:
"generated/"
tasks:
["jshint"]
root:
"img"
imagesDev:
ext:
".html"
files:
[{
}]
webfonts:
jade:
expand:
true
dist:
files:
["vendor/webfonts/**/*.*",
"vendor/components/font-‐awes
pages:
"**/*.jade"
cwd:
"app/img/"
options:
tasks:
["copy:webfontsDev"]
pageRoot:
"app/pages/"
src:
"**"
data:
dest:
"generated/<%=
files.img.root
%>/"
js:
"<%=
minifiedWebRelative
%>"
livereload:
js:
}
jsVendor:
"<%=
minifiedVendorWebRelative
%>"
options:
app:
"app/js/**/*.js"
{
css:
"<%=
files.css.minifiedWebRelative
%>"
livereload:
true
vendor:
[
expand:
true
pkg:
"<%=
pkg
%>"
files:
"dist/**/*.*"
"vendor/components/jquery/jquery.js"
cwd:
"vendor/img/"
files:
[{
"vendor/components/underscore/underscore.js"
src:
"**"
expand:
true
grunt.loadNpmTasks
'grunt-‐bower-‐task'
"vendor/components/angular/angular.js"
dest:
"generated/<%=
files.img.root
%>/"
src:
"<%=
files.jade.pages
%>"
grunt.loadNpmTasks
'grunt-‐coffeelint'
"vendor/js/**/*.js"
}]
cwd:
"<%=
files.jade.pageRoot
%>"
grunt.loadNpmTasks
'grunt-‐contrib-‐clean'
]
imagesDist:
dest:
"dist/"
grunt.loadNpmTasks
'grunt-‐contrib-‐coffee'
concatenatedVendor:
"generated/js/vendor.js"
files:
[{
ext:
".html"
grunt.loadNpmTasks
'grunt-‐contrib-‐concat'
minifiedVendor:
"dist/js/vendor.js"
expand:
true
}]
grunt.loadNpmTasks
'grunt-‐contrib-‐connect'
minifiedVendorWebRelative:
"js/vendor.js"
cwd:
"app/img/"
grunt.loadNpmTasks
'grunt-‐contrib-‐copy'
concatenated:
"generated/js/app.js"
src:
"**"
jshint:
grunt.loadNpmTasks
'grunt-‐contrib-‐cssmin'
minified:
"dist/js/app.js"
dest:
"dist/<%=
files.img.root
%>/"
files:
["<%=
files.js.app
%>"]
grunt.loadNpmTasks
'grunt-‐contrib-‐jshint'
minifiedWebRelative:
"js/app.js"
}
options:
grunt.loadNpmTasks
'grunt-‐contrib-‐less'
{
#
enforcing
options
grunt.loadNpmTasks
'grunt-‐contrib-‐jade'
less:
expand:
true
curly:
true
grunt.loadNpmTasks
'grunt-‐contrib-‐uglify'
app:
"app/css/app.less"
cwd:
"vendor/img/"
eqeqeq:
true
grunt.loadNpmTasks
'grunt-‐contrib-‐watch'
vendor:
"vendor/css/**/*.less"
src:
"**"
latedef:
true
generatedApp:
"generated/css/app.less.css"
dest:
"dist/<%=
files.img.root
%>/"
newcap:
true
grunt.registerTask
'default',
[
generatedVendor:
"generated/css/vendor.less.css"
}]
noarg:
true
'common'
watch:
"app/css/**/*.less"
staticDev:
#
relaxing
options
'dev'
files:
[
boss:
true
]
webfonts:
expand:
true
eqnull:
true
grunt.registerTask
'common',
[
root:
"fonts"
cwd:
"app/static"
sub:
true
'bower'
src:
"**"
#
environment/globals
'coffeelint'
bower:
dest:
'generated'
browser:
true
'jshint'
install:
]
'coffee'
options:
staticDist:
less:
'less'
copy:
false
files:
[
options:
'concat'
expand:
true
paths:
["app/css",
"vendor/css"]
'copy:staticDev'
coffee:
cwd:
"app/static"
compile:
'copy:imagesDev'
compile:
src:
"**"
files:
'copy:webfontsDev'
files:
dest:
'dist'
"<%=
files.less.generatedVendor
%>":
"<%=
files.less.vendor
%>"
'jade:dev'
"<%=
files.coffee.generated
%>":
"<%=
files.coffee.app
%>"
]
"<%=
files.less.generatedApp
%>":
"<%=
files.less.app
%>"
]
webfontsDev:
grunt.registerTask
'dev',
[
coffeelint:
files:
[{
uglify:
'connect'
app:
[
expand:
true
options:
'watch'
"<%=
files.coffee.app
%>"
cwd:
"vendor/webfonts/"
banner:
'/*!
<%=
pkg.name
%>
<%=
grunt.template.today("yyyy-‐mm-‐dd")
%>
*/n'
]
]
src:
"**"
js:
grunt.registerTask
'dist',
[
dest:
"generated/<%=
files.webfonts.root
%>/"
files:
'uglify'
concat:
}
"<%=
files.js.minified
%>":
"<%=
files.js.concatenated
%>"
'cssmin'
css:
{
jsVendor:
'copy:staticDist'
src:
[
expand:
true
files:
'copy:imagesDist'
"<%=
files.less.generatedVendor
%>"
cwd:
"vendor/components/font-‐awesome/fonts/"
"<%=
files.js.minifiedVendor
%>":
"<%=
files.js.concatenatedVendor
%>"
'copy:webfontsDist'
"<%=
files.css.vendor
%>"
src:
"**"
'jade:dist'
"<%=
files.less.generatedApp
%>"
dest:
"generated/<%=
files.webfonts.root
%>/"
clean:
]
"<%=
files.css.app
%>"
}]
bower:
]
src:
bowerDirectory
grunt
bowerDirectory
=
(grunt)
-‐>
dest:
"<%=
files.css.concatenated
%>"
webfontsDist:
js:
bowerrc
=
path.join(process.cwd(),
".bowerrc")
files:
[{
src:
"<%=
files.js.concatenated
%>"
bowerConfig
=
grunt.file.readJSON(bowerrc)
unless
!fs.existsSync(bow
expand:
true
bowerConfig?.directory
||
"vendor/components"
js:
cwd:
"vendor/webfonts/"
css:
src:
[
src:
"**"
src:
"<%=
files.css.concatenated
%>"
"<%=
files.coffee.generated
%>"
dest:
"dist/<%=
files.webfonts.root
%>/"
"<%=
files.js.app
%>"
}
dist:
]
src:
["dist",
"generated"]
dest:
"<%=
files.js.concatenated
%>"
watch:
coffee:
files:
"<%=
files.coffee.app
%>"
tasks:
["coffeelint",
"coffee",
"concat:js"]
13. 'use
strict';
var
util
=
require('util');
var
Orchestrator
=
require('orchestrator');
var
gutil
=
require('gulp-‐util');
var
deprecated
=
require('deprecated');
var
vfs
=
require('vinyl-‐fs');
function
Gulp(){
Orchestrator.call(this);
}
util.inherits(Gulp,
Orchestrator);
Gulp.prototype.task
=
Gulp.prototype.add;
Gulp.prototype.run
=
function(){
//
run()
is
deprecated
as
of
3.5
and
will
be
removed
in
4.0
//
use
task
dependencies
instead
//
impose
our
opinion
of
"default"
tasks
onto
orchestrator
var
tasks
=
arguments.length
?
arguments
:
['default'];
this.start.apply(this,
tasks);
};
Gulp.prototype.src
=
vfs.src;
Gulp.prototype.dest
=
vfs.dest;
Gulp.prototype.watch
=
function
(glob,
opt,
fn)
{
if
(!fn)
{
fn
=
opt;
opt
=
null;
}
//
array
of
tasks
given
if
(Array.isArray(fn))
{
return
vfs.watch(glob,
opt,
function(){
this.start.apply(this,
fn);
}.bind(this));
}
return
vfs.watch(glob,
opt,
fn);
};
//
let
people
use
this
class
from
our
instance
Gulp.prototype.Gulp
=
Gulp;
//
deprecations
deprecated.field('gulp.env
has
been
deprecated.
Use
gulp-‐util.env
or
your
own
CLI
parser
instead.',
console.log,
Gulp.prototype,
'env',
gutil.env);
Gulp.prototype.run
=
deprecated.method('gulp.run()
has
been
deprecated.
Use
task
dependencies
or
gulp.watch
task
triggering
instead.',
console.log,
Gulp.prototype.run);
var
inst
=
new
Gulp();
module.exports
=
inst;
29. //gulpfile.js
var
gulp
=
require('gulp');
var
coffee
=
require('gulp-‐coffee');
var
concat
=
require('gulp-‐concat');
var
uglify
=
require('gulp-‐uglify');
33. gulp.src('app/js/**/*.coffee')
.pipe(coffee())
.pipe(concat('app.js'))
.pipe(gulp.dest('test/js'))
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
34. gulp.task('coffee',
function()
{
gulp.src('app/js/**/*.coffee')
.pipe(coffee())
.pipe(concat('app.js'))
.pipe(gulp.dest('test/js'))
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
38. gulp.task('css',
function()
{
gulp.src('app/css/app.less')
.pipe(less())
.pipe(cssmin())
.pipe(gulp.dest('dist/css'));
});
39. var
bower
=
require('gulp-‐bower');
gulp.task('install',
function()
{
bower();
});
40. gulp.task('css',
['install'],
function()
{
gulp.src('app/css/app.less')
.pipe(less())
.pipe(cssmin())
.pipe(gulp.dest('dist/css'));
});
41. var
bower
=
require('gulp-‐bower');
gulp.task('install',
function()
{
bower();
});
//
Doesn't
work
as
expected
46. //
Option
1:
Callback
gulp.task('stuff',
function(done)
{
doSyncStuff()
done(err);
});
47. var
Q
=
require('q');
//
Option
2:
Promise
gulp.task('stuff',
function()
{
var
deferred
=
Q.defer();
doAsyncStuff(deferred.resolve);
return
deferred.promise;
});
48. //
Option
3:
Return
stream
gulp.task('stuff',
function()
{
var
stream
=
doStreamStuff();
return
stream;
});
50. #
Get
return
stream
for
free!
gulp.task
'stuff',
()
-‐>
doStreamStuff()
gulp.task('stuff',
function()
{
return
doStreamStuff();
});
51. var
bower
=
require('gulp-‐bower');
gulp.task('install',
function()
{
bower();
});
52. var
bower
=
require('gulp-‐bower');
gulp.task('install',
function()
{
return
bower();
//
Win!
});
53. //
Back
to
where
we
were
gulp.task('css',
function()
{
gulp.src('app/css/app.less')
.pipe(less())
.pipe(cssmin())
.pipe(gulp.dest('dist/css'));
});
54. gulp.task('css',
['install'],
function()
{
gulp.src('app/css/app.less')
.pipe(less())
.pipe(cssmin())
.pipe(gulp.dest('dist/css'));
});
63. gulp.task
'js',
()
-‐>
gulp.src
files.coffee
.pipe
coffee()
.pipe
concat('app.js')
.pipe
uglify()
.pipe
gulp.dest('dist/js')
65. gulp.task
'js',
()
-‐>
gulp.src(files.coffee)
.pipe(coffee())
.pipe
concat('app.js')
.pipe
uglify()
.pipe
gulp.dest('dist/js')
66. gulp.task
'js',
()
-‐>
evtstream.concat(
gulp.src(files.coffee)
.pipe(coffee()),
gulp.src(files.js))
.pipe
concat('app.js')
.pipe
uglify()
.pipe
gulp.dest('dist/js')
67. gulp.task
'js',
()
-‐>
es.concat(
gulp.src(files.coffee)
.pipe(coffee()),
gulp.src(files.js))
.pipe
concat('app.js')
.pipe
uglify()
.pipe
gulp.dest('dist/js')
68. gulp.task
'js',
()
-‐>
sq
=
streamq
{objectmode:true}
sq.queue
gulp.src(files.coffee)
.pipe(coffee()
sq.queue
gulp.src(files.js)
sq.done().pipe
concat('app.js')
.pipe
uglify()
.pipe
gulp.dest('dist/js')
74. gulp.task
'css',
['install'],
()
-‐>
gulp.src
files.less
.pipe
less().on('error',(err)-‐>
console.log(''+err)
if
err
)
#
Ick.
.pipe
cssmin()
.pipe
gulp.dest('dist/css')
75. plumber
=
require
'gulp-‐plumber'
gulp.task
'css',
['install'],
()
-‐>
gulp.src
files.less
.pipe
plumber()
#Win!
.pipe
less()
.pipe
cssmin()
.pipe
gulp.dest('dist/css')
79. gulp.src
'app/css/*.css'
.pipe
concat('app.css')
.pipe(if
gutil.env.dest
==
'prod'
then
cssmin()
else
gutil.noop())
.pipe
gulp.dest('dist/css')
80. gulp.src
'app/css/*.css'
.pipe
concat('app.css')
.pipe(if
gutil.env.dest
==
'prod'
then
cssmin()
else
gutil.noop())
.pipe
gulp.dest('dist/css')
82.
echo
Total
Files:
$(
find
.
-‐type
f
-‐print
|
wc
-‐l)
Total
Files:
1000
echo
watch
will
vomit
84. gruntfile.coffee
timer
=
require
"grunt-‐timer"
fs
=
require
'fs'
path
=
require
'path'
server
=
require
'./config/server'
urlrouter
=
require
'urlrouter'
module.exports
=
(grunt)
-‐>
timer.init
grunt
#
Project
configuration.
grunt.initConfig
pkg:
grunt.file.readJSON
'package.json'
files:
coffee:
app:
"app/js/**/*.coffee"
generated:
"generated/js/app.coffee.js"
css:
vendor:
"vendor/css/**/*.css"
app:
"app/css/**/*.css"
concatenated:
"generated/css/app.css"
minified:
"dist/css/app.css"
minifiedWebRelative:
"css/app.css"
img:
root:
"img"
jade:
pages:
"**/*.jade"
pageRoot:
"app/pages/"
js:
app:
"app/js/**/*.js"
vendor:
[
"vendor/components/jquery/jquery.js"
"vendor/components/underscore/underscore.js"
"vendor/components/angular/angular.js"
"vendor/js/**/*.js"
]
concatenatedVendor:
"generated/js/vendor.js"
minifiedVendor:
"dist/js/vendor.js"
minifiedVendorWebRelative:
"js/vendor.js"
concatenated:
"generated/js/app.js"
minified:
"dist/js/app.js"
minifiedWebRelative:
"js/app.js"
less:
app:
"app/css/app.less"
vendor:
"vendor/css/**/*.less"
generatedApp:
"generated/css/app.less.css"
generatedVendor:
"generated/css/vendor.less.css"
watch:
"app/css/**/*.less"
webfonts:
root:
"fonts"
bower:
install:
options:
copy:
false
coffee:
compile:
files:
"<%=
files.coffee.generated
%>":
"<%=
files.coffee.app
%>"
coffeelint:
app:
[
"<%=
files.coffee.app
%>"
]
concat:
css:
src:
[
"<%=
files.less.generatedVendor
%>"
"<%=
files.css.vendor
%>"
"<%=
files.less.generatedApp
%>"
"<%=
files.css.app
%>"
]
dest:
"<%=
files.css.concatenated
%>"
js:
src:
[
"<%=
files.coffee.generated
%>"
"<%=
files.js.app
%>"
]
dest:
"<%=
files.js.concatenated
%>"
jsVendor:
src:
["<%=
files.js.vendor
%>"]
dest:
"<%=
files.js.concatenatedVendor
%>"
connect:
server:
options:
port:
8000
base:
'generated'
open:
true
middleware:
(connect,
options)
-‐>
middlewares
=
[];
if
(!Array.isArray(options.base))
options.base
=
[options.base]
directory
=
options.directory
||
options.base[options.base.length
-‐
1]
options.base.forEach
(base)
-‐>
#
Serve
static
files.
middlewares.push(connect.static(base))
middlewares.push
urlrouter(server.drawRoutes)
#
Make
directory
browse-‐able.
middlewares.push
connect.directory(directory)
middlewares
copy:
imagesDev:
files:
[{
expand:
true
cwd:
"app/img/"
src:
"**"
dest:
"generated/<%=
files.img.root
%>/"
}
{
expand:
true
cwd:
"vendor/img/"
src:
"**"
dest:
"generated/<%=
files.img.root
%>/"
}]
imagesDist:
files:
[{
expand:
true
cwd:
"app/img/"
src:
"**"
dest:
"dist/<%=
files.img.root
%>/"
}
{
expand:
true
cwd:
"vendor/img/"
src:
"**"
dest:
"dist/<%=
files.img.root
%>/"
}]
staticDev:
files:
[
expand:
true
cwd:
"app/static"
src:
"**"
dest:
'generated'
]
staticDist:
files:
[
expand:
true
cwd:
"app/static"
src:
"**"
dest:
'dist'
]
webfontsDev:
files:
[{
expand:
true
cwd:
"vendor/webfonts/"
src:
"**"
dest:
"generated/<%=
files.webfonts.root
%>/"
}
{
expand:
true
cwd:
"vendor/components/font-‐awesome/fonts/"
src:
"**"
dest:
"generated/<%=
files.webfonts.root
%>/"
}]
webfontsDist:
files:
[{
expand:
true
cwd:
"vendor/webfonts/"
src:
"**"
dest:
"dist/<%=
files.webfonts.root
%>/"
}
{
expand:
true
cwd:
"vendor/components/font-‐awesome/fonts/"
src:
"**"
dest:
"dist/<%=
files.webfonts.root
%>/"
}]
cssmin:
compress:
files:
"<%=
files.css.minified
%>":
"<%=
files.css.concatenated
%>"
css:
files:
["<%=
files.css.vendor
%>",
"<%=
files.css.app
%>"]
tasks:
["concat:css"]
jade:
dev:
options:
pretty:
true
data:
js:
"<%=
files.js.minifiedWebRelative
%>"
jsVendor:
"<%=
files.js.minifiedVendorWebRelative
%>"
css:
"<%=
files.css.minifiedWebRelative
%>"
pkg:
"<%=
pkg
%>"
files:
[{
expand:
true
src:
"<%=
files.jade.pages
%>"
cwd:
"<%=
files.jade.pageRoot
%>"
dest:
"generated/"
ext:
".html"
}]
dist:
options:
data:
js:
"<%=
minifiedWebRelative
%>"
jsVendor:
"<%=
minifiedVendorWebRelative
%>"
css:
"<%=
files.css.minifiedWebRelative
%>"
pkg:
"<%=
pkg
%>"
files:
[{
expand:
true
src:
"<%=
files.jade.pages
%>"
cwd:
"<%=
files.jade.pageRoot
%>"
dest:
"dist/"
ext:
".html"
}]
js:
files:
["<%=
files.js.vendor
%>",
"<%=
files.js.app
%>"]
tasks:
["concat:js"]
jshint:
files:
["<%=
files.js.app
%>"]
options:
#
enforcing
options
curly:
true
eqeqeq:
true
latedef:
true
newcap:
true
noarg:
true
#
relaxing
options
boss:
true
eqnull:
true
sub:
true
#
environment/globals
browser:
true
less:
options:
paths:
["app/css",
"vendor/css"]
compile:
files:
"<%=
files.less.generatedVendor
%>":
"<%=
files.less.vendor
%>"
"<%=
files.less.generatedApp
%>":
"<%=
files.less.app
%>"
uglify:
options:
banner:
'/*!
<%=
pkg.name
%>
<%=
grunt.template.today("yyyy-‐mm-‐dd")
%>
*/n'
js:
files:
"<%=
files.js.minified
%>":
"<%=
files.js.concatenated
%>"
jsVendor:
files:
"<%=
files.js.minifiedVendor
%>":
"<%=
files.js.concatenatedVendor
%>"
clean:
bower:
src:
bowerDirectory
grunt
js:
src:
"<%=
files.js.concatenated
%>"
css:
src:
"<%=
files.css.concatenated
%>"
dist:
src:
["dist",
"generated"]
watch:
coffee:
files:
"<%=
files.coffee.app
%>"
tasks:
["coffeelint",
"coffee",
"concat:js"]
images:
files:
["app/img/**/*.*",
"vendor/img/**/*.*"]
tasks:
["copy:imagesDev"]
jade:
files:
["<%=
files.jade.pageRoot
%>/<%=
files.jade.pages
%>"]
tasks:
["jade:dev"]
less:
files:
[
"<%=
files.less.vendor
%>"
"<%=
files.less.watch
%>"
]
tasks:
["less",
"concat:css"]
lint:
files:
"<%=
files.js.app
%>"
tasks:
["jshint"]
webfonts:
files:
["vendor/webfonts/**/*.*",
"vendor/components/font-‐awesome/fonts/**/*.*"]
tasks:
["copy:webfontsDev"]
livereload:
options:
livereload:
true
files:
"dist/**/*.*"
grunt.loadNpmTasks
'grunt-‐bower-‐task'
grunt.loadNpmTasks
'grunt-‐coffeelint'
grunt.loadNpmTasks
'grunt-‐contrib-‐clean'
grunt.loadNpmTasks
'grunt-‐contrib-‐coffee'
grunt.loadNpmTasks
'grunt-‐contrib-‐concat'
grunt.loadNpmTasks
'grunt-‐contrib-‐connect'
grunt.loadNpmTasks
'grunt-‐contrib-‐copy'
grunt.loadNpmTasks
'grunt-‐contrib-‐cssmin'
grunt.loadNpmTasks
'grunt-‐contrib-‐jshint'
grunt.loadNpmTasks
'grunt-‐contrib-‐less'
grunt.loadNpmTasks
'grunt-‐contrib-‐jade'
grunt.loadNpmTasks
'grunt-‐contrib-‐uglify'
grunt.loadNpmTasks
'grunt-‐contrib-‐watch'
grunt.registerTask
'default',
[
'common'
'dev'
]
grunt.registerTask
'common',
[
'bower'
'coffeelint'
'jshint'
'coffee'
'less'
'concat'
'copy:staticDev'
'copy:imagesDev'
'copy:webfontsDev'
'jade:dev'
]
grunt.registerTask
'dev',
[
'connect'
'watch'
]
grunt.registerTask
'dist',
[
'uglify'
'cssmin'
'copy:staticDist'
'copy:imagesDist'
'copy:webfontsDist'
'jade:dist'
]
bowerDirectory
=
(grunt)
-‐>
bowerrc
=
path.join(process.cwd(),
".bowerrc")
bowerConfig
=
grunt.file.readJSON(bowerrc)
unless
!fs.existsSync(bowerrc)
bowerConfig?.directory
||
"vendor/components"
85. gulpfile.coffee
gulp
=
require
'gulp'
gutil
=
require
'gulp-‐util'
fs
=
require
'fs'
path
=
require
'path'
bower
=
require
'gulp-‐bower'
clean
=
require
'gulp-‐clean'
coffee
=
require
'gulp-‐coffee'
coffeelint
=
require
'gulp-‐coffeelint'
concat
=
require
'gulp-‐concat'
jade
=
require
'gulp-‐jade'
jslint
=
require
'gulp-‐jshint'
jslintReporter
=
require
'jshint-‐stylish'
less
=
require
'gulp-‐less'
cssmin
=
require
'gulp-‐minify-‐css'
connect
=
require
'gulp-‐connect'
uglify
=
require
'gulp-‐uglify'
es
=
require
'event-‐stream'
pkg
=
require
'./package.json'
server
=
require
'./config/server'
urlrouter
=
require
'urlrouter'
output
=
css:
'css/app.css'
jsApp:
'js/app.js'
jsVendor:
'js/vendor.js'
files
=
coffee:
'app/js/**/*.coffee'
img:
'app/img/**/*.*'
static:
'app/static/**/*.*'
webfonts:
[
'vendor/webfonts/**/*.*'
'vendor/components/font-‐awesome/fonts/**/*.*'
]
jade:
'app/pages/**/*.jade'
js:
app:
['app/js/**/*.js']
vendor:
[
'vendor/components/jquery/jquery.min.js'
'vendor/components/underscore/underscore-‐min.js'
'vendor/components/angular/angular.min.js'
'vendor/js/**/*.js'
]
less:
app:
'app/css/app.less'
watch:
[
'app/css/**'
'vendor/components/bootstrap/less/**'
]
config
=
jshint:
#
enforcing
options
curly:
true
eqeqeq:
true
latedef:
true
newcap:
true
noarg:
true
#
relaxing
options
boss:
true
eqnull:
true
sub:
true
#
environment/globals
browser:
true
jade:
pretty:
true
data:
js:
output.jsApp
jsVendor:
output.jsVendor
css:
output.css
pkg:
pkg
server:
port:
8000
base:
'generated'
livereload:
true
open:
true
middleware:
(connect,
options)
-‐>
middlewares
=
[];
if
(!Array.isArray(options.base))
options.base
=
[options.base]
directory
=
options.directory
||
options.base[options.base.length
-‐
1]
options.base.forEach
(base)
-‐>
#
Serve
static
files.
middlewares.push(connect.static(base))
middlewares.push
urlrouter(server.drawRoutes)
#
Make
directory
browse-‐able.
middlewares.push
connect.directory(directory)
middlewares
gulp.task
'default',
['lint','build']
gulp.task
'run',
['lint','build','server','watch']
gulp.task
'build',
[
'install'
'js'
'css'
'jade'
'copy'
]
gulp.task
'install',
()
-‐>
bower()
gulp.task
'lint',
['coffeelint','jslint']
gulp.task
'coffeelint',
()
-‐>
gulp.src(files.coffee)
.pipe(coffeelint())
.pipe(coffeelint.reporter())
gulp.task
'jslint',
()
-‐>
gulp.src(files.js.app)
.pipe(jslint(config.jshint))
.pipe(jslint.reporter(jslintReporter))
gulp.task
'jade',
()
-‐>
gulp.src(files.jade)
.pipe(jade(config.jade))
.pipe(gulp.dest('./generated'))
.pipe(gulp.dest('./dist'))
gulp.task
'jsApp',
()
-‐>
es.concat(
gulp.src(files.coffee).pipe(coffee()),
gulp.src(files.js.app)
).pipe(concat(output.jsApp))
.pipe(gulp.dest('./generated'))
.pipe(uglify())
.pipe(gulp.dest('./dist'))
gulp.task
'jsVendor',
['install'],
()
-‐>
gulp.src(files.js.vendor)
.pipe(concat(output.jsVendor))
.pipe(gulp.dest('./generated'))
.pipe(gulp.dest('./dist'))
gulp.task
'js',
['jsApp','jsVendor']
gulp.task
'css',
['install'],
()
-‐>
gulp.src(files.less.app)
.pipe(plumber())
.pipe(less())
.pipe(concat(output.css))
.pipe(gulp.dest('./generated'))
.pipe(cssmin())
.pipe(gulp.dest('./dist'))
gulp.task
'clean',
()
-‐>
gulp.src(['./dist','./generated',
bowerDirectory()])
.pipe(clean())
gulp.task
'copy',
['install'],
()
-‐>
es.concat(
gulp.src(files.img)
.pipe(gulp.dest('./generated/img'))
.pipe(gulp.dest('./dist/img')),
gulp.src(files.static)
.pipe(gulp.dest('./generated/'))
.pipe(gulp.dest('./dist/')),
gulp.src(files.webfonts)
.pipe(gulp.dest('./generated/fonts'))
.pipe(gulp.dest('./dist/fonts'))
)
gulp.task
'watch',
()
-‐>
gulp.watch
files.coffee,
['coffeelint','jsApp']
gulp.watch
files.js.app,
['jslint','jsApp']
gulp.watch
files.js.vendor,
['jsVendor']
gulp.watch
files.jade.pages,
['jade']
gulp.watch
files.less.watch,
['css']
gulp.watch
[files.img,
files.webfonts,
files.static],
['copy']
gulp.task
'server',
['build'],
connect.server(config.server)
bowerDirectory
=
()
-‐>
bowerpath
=
path.join(process.cwd(),
".bowerrc")
bowerrc
=
fs.readFileSync(bowerpath)
unless
!fs.existsSync
bowerpath
bowerConfig
=
JSON.parse(bowerrc)
if
bowerrc?
bowerConfig?.directory
||
"vendor/components"
87. bower
=
require
'gulp-‐bower'
coffeelint
=
require
'gulp-‐coffeelint'
clean
=
require
'gulp-‐clean'
coffee
=
require
'gulp-‐coffee'
concat
=
require
'gulp-‐concat'
connect
=
require
'gulp-‐connect'
#
copy
included
via
.dest
cssmin
=
require
'gulp-‐minify-‐css'
jade
=
require
'gulp-‐jade'
jslint
=
require
'gulp-‐jshint'
less
=
require
'gulp-‐less'
uglify
=
require
'gulp-‐uglify'
#
watch
included
via
.watch
88. git
co
grunt
time
grunt
>
/dev/null
real
0m5.114s
user
0m4.802s
sys
0m0.214s
89. git
co
grunt
time
grunt
>
/dev/null
real
0m5.114s
user
0m4.802s
sys
0m0.214s
git
co
gulp
time
gulp
>
/dev/null
real
0m2.811s
user
0m2.601s
sys
0m0.241s