Skip to content

Instantly share code, notes, and snippets.

@corbanbrook
Created February 4, 2014 16:50
Show Gist options
  • Select an option

  • Save corbanbrook/8807582 to your computer and use it in GitHub Desktop.

Select an option

Save corbanbrook/8807582 to your computer and use it in GitHub Desktop.
# Gulp and plugins
gulp = require('gulp')
gutil = require('gulp-util')
plugins = require("gulp-load-plugins")(scope: ["dependencies", "devDependencies"])
# Utilities
grunt = require('grunt')
glob = require('glob')
path = require('path')
fs = require('fs')
q = require('q')
_ = require('lodash')
# Connect server and middleware
connect = require('connect')
livereload = require('connect-livereload')
rewrite = require('connect-modrewrite')
proxy = require('proxy-middleware')
http = require('http')
url = require('url')
# Tiny-Livereload server
livereloadServer = require('tiny-lr')()
config =
env: process.env['NODE_ENV'] || 'development'
config: 'config'
build: 'build'
dist: 'dist'
src: 'src'
test: 'test'
host: 'localhost'
port: 9000
livereloadPort: 44444
require('jsonminify')
readJSON = (filepath) ->
data = JSON.minify(fs.readFileSync(filepath, 'utf8'))
JSON.parse(data)
# Config json
appConfig = readJSON(path.join(config.config, '/settings.json'))[config.env]
scriptsConfig = readJSON(path.join(config.src, '/scripts.json'))
runTaskWithOptions = (taskName, options) ->
throw taskName + ' task not found!' unless gulp.hasTask(taskName)
task = gulp.tasks[taskName]
taskWithOptions = _.clone(gulp.tasks[taskName])
taskWithOptions.fn = (cb) -> task.fn(cb, options)
gulp._runTask(taskWithOptions)
# Default task - Builds and starts the development server
gulp.task 'default', ->
gulp.start('server')
gulp.task 'build', ['clean'], ->
deferred = q.defer()
return gulp.start(
'public'
'templates'
'stylus'
'coffee'
'scripts'
'index'
)
# deferred.promise
gulp.task 'server', ['build'], ->
gulp.start(
'connect'
'watch'
)
gulp.task 'dist', ['build'], ->
# Cleans the build
gulp.task 'clean', ->
gulp.src(config.build, { read: false })
.pipe(plugins.clean({ force: true }))
# Copy public files to build
gulp.task 'public', ->
gulp.src(path.join(config.src, '/public/**/*'))
.pipe(gulp.dest(path.join(config.build, '/public')))
# Compiles all stylus and copies to build
gulp.task 'stylus', ->
imports = [
path.join(config.src, '/app/**/*.styl')
path.join(config.src, '/components/**/*.styl')
path.join('!' + config.src, '/app/**/_*.styl')
]
# Prepares import strings to be appended to the app.styl document before stylus compile
importsString = _.map(grunt.file.expand(imports), (filepath) -> '@import "' + filepath + '";').join("\n")
gulp.src(path.join(config.src, '/styles/app.styl'))
.pipe(plugins.footer(importsString))
.pipe(plugins.stylus({
set: ['linenos']
paths: ['.', path.join(config.src, '/styles')]
use: ['nib']
}))
.on('error', gutil.log)
.on('error', gutil.beep)
.pipe(gulp.dest(path.join(config.build, '/styles/')))
.pipe(plugins.livereload(livereloadServer))
# Compiles all coffeescript and copies to build
gulp.task 'coffee', (cb, filepath) ->
gulp.src(filepath || path.join(config.src, '/**/*.coffee'), base: config.src)
.pipe(plugins.coffee(sourceMap: true, sourceRoot: ''))
.on('error', gutil.log)
.on('error', gutil.beep)
.pipe(gulp.dest(config.build))
.pipe(plugins.livereload(livereloadServer))
# Copy all HTML templates to build
gulp.task 'templates', (cb, filepath) ->
gulp.src(filepath || [
path.join(config.src, '/**/*.html')
path.join('!' + config.src, '/index.html')
], base: config.src)
.pipe(gulp.dest(config.build))
.pipe(plugins.livereload(livereloadServer))
# Copy all the scripts from the src dir that are specified in scrips.json to the build dir
gulp.task 'scripts', ->
scripts = grunt.file.expand(cwd: config.src, scriptsConfig)
gulp.src(scripts, cwd: config.src, base: config.src)
.pipe(gulp.dest(config.build))
# Compiles index.html file with appConfig, scripts, and stylesheets
gulp.task 'index', ['coffee', 'scripts'], ->
scripts = _.map(grunt.file.expand(cwd: config.build, scriptsConfig), (filepath) ->
path.join('/', filepath)
)
#console.log(scripts);
gulp.src(path.join(config.src, '/index.html'))
.pipe(plugins.template({
appConfig: JSON.stringify(appConfig)
scripts: scripts
stylesheets: ['/styles/app.css']
}))
.pipe(gulp.dest(config.build))
# Connect server and middleware
gulp.task 'connect', (cb) ->
deferred = q.defer()
app = connect()
# Proxy all api routes to the backend
apiUrl = url.parse('http://0.0.0.0:3000/api')
app.use(proxy(_.extend({ route: '/api' }, apiUrl)))
# To support HTML5 pushstate we must rewrite all non-file routes to the index
app.use(rewrite(['!(\\..+)$ /index.html [L]']))
# Add livereload snippet to index.html
app.use(livereload(port: config.livereloadPort))
# Static search paths
app.use(connect.static(config.build))
app.use(connect.static(path.join(config.build, 'public')))
app.use(connect.static(config.src))
server = http.createServer(app)
server.listen(config.port)
server.on 'listening', ->
deferred.resolve()
console.log('Started connect web server on http://localhost:' + config.port)
deferred.promise
gulp.task 'watch', ['connect'], ->
livereloadServer.listen config.livereloadPort, (err) ->
return console.log(err) if err
# Watch .styl files
gulp.watch([
path.join(config.src, '/**/*.styl')
path.join('!' + config.src, '/vendor/**/*.styl')
], ['stylus'])
# Watch .coffee files
gulp.watch([
path.join(config.src, '/**/*.coffee')
path.join('!' + config.src, '/vendor/**/*.coffee')
], (ev) ->
# Only compile the coffee script file that changed -- fast!
runTaskWithOptions('coffee', ev.path)
)
# Watch .js files
# gulp.watch([
# path.join(config.src, '/**/*.js')
# path.join('!' + config.src, '/vendor/**/*.js')
# ], ['js'])
# Watch .html files
gulp.watch([
path.join(config.src, '/**/*.html')
path.join('!' + config.src, '/index.html')
path.join('!' + config.src, '/vendor/**/*.html')
], (ev) ->
# Only copy the html file that changed
runTaskWithOptions('templates', ev.path)
)
# gulp.watch([
# path.join(config.build, '/**/*.html')
# path.join(config.build, '/**/*.css')
# path.join(config.build, '/**/*.js')
# ], ['refresh'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment