Gulp is used to quickly generate all js and css files. In our project you do not
need to call gulp directly. Simply use npm install
and npm start
and the
right gulp
actions will be called.
gulp = require 'gulp'
coffee = require 'gulp-coffee'
common = require 'gulp-commonjs'
concat = require 'gulp-concat'
connect = require 'gulp-connect'
gulpif = require 'gulp-if'
gutil = require 'gulp-util'
insert = require 'gulp-insert'
jade = require 'gulp-jade'
rename = require 'gulp-rename'
stylus = require 'gulp-stylus'
uglify = require 'gulp-uglify'
Destination directory
dest = "build"
paths =
stylus: ["css/index.styl"]
coffee: [
"app/**/*.coffee"
"app/**/*.litcoffee"
]
js: ["app/**/*.js"]
jade: ["app/**/*.jade"]
Libs will be directly added without a commonjs wrapper:
libs: [
"node_modules/jade/runtime.js"
"node_modules/commonjs-require-definition/require.js"
]
Node modules which will be included with a commonjs wrapper:
modules: [
"es5-shimify"
"json2ify"
"jquery"
"jquery-ui"
"jquery.browser/dist/jquery.browser.js"
"moment"
"pluralize"
"q"
"spine/lib/spine"
"spine/lib/local"
"spine/lib/relation"
"spine/lib/ajax"
"spine/lib/route"
"spine/lib/manager"
"spine/lib/list"
]
Names for the generated files
targets =
css : "application.css"
js : "application.js"
jsMin : "application.min.js"
jade : "templates.js"
lib : "libs.js"
scripts : "scripts.js"
coffee : "coffee.js"
modules : "modules.js"
When a file generates an error, we report it and then continue the stream
reportError = (err) ->
gutil.log err
@emit 'end'
Convert stylus files into one .css
file.
generateCss = ->
gulp.src paths.stylus
.pipe stylus()
.pipe concat targets.css
.pipe gulp.dest dest
.pipe connect.reload()
gulp.task "stylus", generateCss
Modules are node_modules which are added to the client code. These are all wrapped in a commonjs wrapper.
gulp.task "modules", ->
files = (require.resolve(module) for module in paths.modules)
gulp.src(files, base: __dirname)
.pipe rename (path) ->
path.extname = ""
path.dirname = path.dirname
.split('node_modules/')[1]
.split('/dist')[0]
path.basename = '' if path.basename is 'index'
path.dirname = '' if path.basename in ['spine', path.dirname]
path
.pipe common()
.pipe concat targets.modules
.pipe gulp.dest dest
Transform all the .jade
files to templates.js
with commonjs wrappers
around them.
gulp.task "jade", ->
gulp.src paths.jade
.pipe jade(client: true).on('error', reportError)
.pipe insert.prepend "module.exports = "
.pipe rename extname: ""
.pipe common()
.pipe concat targets.jade
.pipe gulp.dest dest
All .coffee
and .js
files are combined into one .js
file with
a commonjs wrapper around each one.
gulp.task "scripts", ->
gulp.src paths.js
.pipe rename extname: ""
.pipe common()
.pipe concat targets.scripts
.pipe gulp.dest dest
gulp.task "coffee", ->
gulp.src paths.coffee
.pipe coffee(bare: true).on('error', reportError)
.pipe rename extname: ""
.pipe common()
.pipe concat targets.coffee
.pipe gulp.dest dest
Libs are directly added without a commonjs wrapper. Note: this shouldn't be the default, but special case only.
gulp.task "libs", ->
gulp.src paths.libs
.pipe concat targets.lib
.pipe gulp.dest dest
Do all the js things
gulp.task "js", ["libs", "modules", "scripts", "coffee", "jade"], (next) ->
next()
Combine the above results into one .js
file.
combineJs = ->
# We need to rethrow jade errors to see them
rethrow = (err, filename, lineno) -> throw err
files = [
targets.lib
targets.modules
targets.scripts
targets.coffee
targets.jade
]
sources = files.map (file) -> "#{dest}/#{file}"
gulp.src sources
.pipe concat targets.js
.pipe insert.append "jade.rethrow = #{rethrow.toLocaleString()};"
.pipe gulp.dest dest
.pipe connect.reload()
gulp.task "combine", combineJs
Build js, stylus and combine js
gulp.task "build", ["js"], ->
generateCss()
combineJs()
Minify end results
gulp.task "minify", ->
gulp.src "#{dest}/#{targets.js}"
.pipe uglify()
.pipe concat targets.jsMin
.pipe gulp.dest dest
The connect server has livereload
support, which means that css and js are
automatically refreshed in the browser.
gulp.task "server", ["build"], connect.server
root: [dest]
port: 9294
livereload: true
middleware: ->
[
(req, res, next) ->
res.setHeader 'Access-Control-Allow-Origin', '*'
res.setHeader 'Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'
res.setHeader 'Access-Control-Allow-Headers', 'Content-Type'
next()
]
gulp.task "watch", ["server"], ->
gulp.watch 'css/*.styl', {interval: 1000}, ['stylus']
gulp.watch paths.jade, {interval: 2000}, ['jade']
gulp.watch paths.coffee, {interval: 2000}, ['coffee']
gulp.watch paths.js, {interval: 2000}, ['scripts']
files = [targets.scripts, targets.jade, targets.coffee]
sources = ("#{dest}/#{file}" for file in files)
gulp.watch sources, {interval: 1000}, ['combine']
gulp.task "default", ["watch"]
The fact that I great multiple files is for testing purposes.