Created
March 25, 2015 22:45
-
-
Save troywarr/199908fd29c8c47d269e to your computer and use it in GitHub Desktop.
Complete gulpfile to demonstrate an issue using BrowserSync.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gulp = require('gulp') | |
gulpIf = require('gulp-if') | |
less = require('gulp-less') | |
minifyCSS = require('gulp-minify-css') | |
notify = require('gulp-notify') | |
rename = require('gulp-rename') | |
imageMin = require('gulp-imagemin') | |
uglify = require('gulp-uglify') | |
jade = require('gulp-jade') | |
svgSprite = require('gulp-svg-sprite') | |
plumber = require('gulp-plumber') | |
bump = require('gulp-bump') | |
coffeeLint = require('gulp-coffeelint') | |
size = require('gulp-size') | |
gutil = require('gulp-util') | |
cache = require('gulp-cached') | |
sourcemaps = require('gulp-sourcemaps') | |
templatizer = require('templatizer') | |
browserify = require('browserify') | |
transform = require('vinyl-transform') | |
pngCrush = require('imagemin-pngcrush') | |
del = require('del') | |
opn = require('opn') | |
browserSync = require('browser-sync') | |
_ = require('lodash') | |
# fs = require('fs') | |
# htmlify = require('gulp-angular-htmlify') | |
# rev = require('gulp-rev') | |
# concat = require('gulp-concat') | |
# mocha = require('gulp-mocha') | |
# karma = require('gulp-karma') | |
# protractorLib = require('gulp-protractor') | |
# changed = require('gulp-changed') | |
# templateCache = require('gulp-angular-templatecache') | |
# chai = require('chai') # TODO: needed? | |
### SHORTCUTS ### | |
buildTasks = [ | |
'root' | |
'fonts' | |
'styles' | |
'scripts' | |
'images' | |
'jade-js' | |
'jade-html' | |
'ng-html' | |
'ng-views' | |
] | |
# protractor = protractorLib.protractor | |
# webdriver_standalone = protractorLib.webdriver_standalone | |
# webdriver_update = protractorLib.webdriver_update | |
### ENVIRONMENT ### | |
PROD = gutil.env.prod | |
DEV = !PROD | |
### PATHS ### | |
paths = # NOTE: avoid relative paths that start with ./ (see: http://stackoverflow.com/a/22391756/167911) | |
root: '.' | |
src: 'src' | |
dist: 'dist' | |
bower: 'bower_components' | |
npm: 'node_modules' | |
start: 'index.html' # entry point loaded in browser | |
coffeelint: 'coffeelint.json' | |
hobo: '../hobofest/public/ng' | |
### CONFIG ### | |
opts = | |
jade: | |
doctype: 'html' # prevent attribute expansion; needed for Angular directives | |
rev: | |
merge: true # merge with existing rev-manifest.json (don't overwrite) | |
size: | |
showFiles: true # show the size of individual files | |
uglify: | |
mangle: false # don't mangle names (prevents Angular DI breakage) | |
### UTILS ### | |
# error handling | |
handleError = (err) -> | |
notify.onError( | |
title: 'Gulp Error' | |
message: "#{err.message}" | |
)(err) | |
@emit 'end' | |
# bump version | |
# e.g., `gulp bump --minor` | |
gulp.task 'bump', -> | |
gulp | |
.src [ | |
"#{paths.root}/bower.json" | |
"#{paths.root}/package.json" | |
] | |
.pipe bump | |
type: switch | |
when argv.major then 'major' | |
when argv.minor then 'minor' | |
else 'patch' | |
.pipe gulp.dest paths.root | |
# start BrowserSync server | |
gulp.task 'serve', -> | |
browserSync | |
server: | |
baseDir: paths.dist | |
directory: true | |
open: false | |
port: 3001 | |
ui: | |
port: 3003 | |
startPath: paths.start | |
, (err, bs) -> | |
url = bs.options.getIn(['urls', 'local']).replace(':3001/', ':3002/') # use nginx proxy | |
opn(url) | |
console.log("Started BrowserSync via nginx proxy at #{url}") | |
# lint scripts | |
# TODO: add JS support | |
gulp.task 'lint', -> | |
gulp | |
.src "#{paths.src}/scripts/**/*.coffee" | |
.pipe coffeeLint(paths.coffeelint) | |
.pipe coffeeLint.reporter() | |
### HOBO STACK INTEGRATION ### | |
# copy output to Hobo stack | |
gulp.task 'hobo', -> | |
gulp | |
.src '**/*.*', | |
cwd: paths.dist | |
.pipe cache 'hobo' | |
.pipe gulp.dest paths.hobo | |
# clean Hobo stack output | |
gulp.task 'clean:hobo', (done) -> | |
del paths.hobo, | |
force: true | |
, done | |
# watch dist output for changes we'll need to copy to Hobo stack | |
gulp.task 'watch:hobo', -> | |
gulp.watch "#{paths.dist}/**/*.*", ['hobo'] | |
### WRAPPERS ### | |
# clean entire dist folder | |
gulp.task 'clean:dist', (done) -> | |
del paths.dist, done | |
# clean everything | |
gulp.task 'clean', [ | |
'clean:dist' | |
'clean:hobo' | |
] | |
# watch everything | |
gulp.task 'watch', [ | |
'watch:root' | |
'watch:fonts' | |
'watch:styles' | |
'watch:scripts' | |
'watch:images' | |
'watch:jade-js' | |
'watch:jade-html' | |
'watch:ng-html' | |
'watch:ng-views' | |
'watch:icons' | |
'watch:hobo' | |
] | |
### SRC: ROOT ### | |
# copy root directory files (CNAME, robots.txt, etc.) | |
gulp.task 'root', -> | |
gulp | |
.src "#{paths.src}/root/**/*" | |
.pipe cache 'root' | |
.pipe gulp.dest paths.dist | |
# clean 'root' task output | |
gulp.task 'clean:root', (done) -> | |
del [ | |
"#{paths.dist}/CNAME" | |
"#{paths.dist}/iframeResizer.contentWindow.min.js" | |
"#{paths.dist}/iframeResizer.min.js" | |
"#{paths.dist}/robots.txt" | |
], done | |
# watch root files | |
gulp.task 'watch:root', -> | |
gulp.watch "#{paths.src}/root/**/*", ['root', browserSync.reload] | |
### SRC: FONTS ### | |
# copy fonts | |
gulp.task 'fonts', -> | |
gulp | |
.src [ | |
"#{paths.src}/fonts/**/*" # add new fonts here (4 common formats) | |
"#{paths.npm}/bootstrap/dist/fonts/**/*" | |
] | |
.pipe cache 'fonts' | |
.pipe gulp.dest "#{paths.dist}/fonts" | |
# clean font files | |
gulp.task 'clean:fonts', -> | |
del "#{paths.dist}/fonts/**/*.*", done | |
# watch font files | |
gulp.task 'watch:fonts', -> | |
gulp.watch [ | |
"#{paths.src}/fonts/**/*" | |
"#{paths.npm}/bootstrap/dist/fonts/**/*" | |
], ['fonts', browserSync.reload] | |
### SRC: STYLES ### | |
# compile LESS and minify | |
gulp.task 'styles', ['clean:styles'], -> | |
gulp | |
.src "#{paths.src}/styles/index.less" | |
.pipe plumber handleError | |
.pipe gulpIf DEV, sourcemaps.init() | |
.pipe less() | |
.pipe gulpIf DEV, sourcemaps.write() | |
.pipe gulpIf PROD, minifyCSS() | |
# .pipe gulpIf PROD, rev() | |
.pipe rename | |
extname: '.min.css' | |
.pipe size opts.size | |
.pipe gulp.dest "#{paths.dist}/styles" | |
# .pipe gulpIf PROD, rev.manifest opts.rev | |
# .pipe gulpIf PROD, gulp.dest paths.root | |
.pipe gulpIf DEV, browserSync.reload | |
stream: true | |
# clean stylesheets | |
gulp.task 'clean:styles', (done) -> | |
del "#{paths.dist}/styles/**/*.*", done | |
# watch LESS | |
gulp.task 'watch:styles', -> | |
gulp.watch "#{paths.src}/styles/**/*.less", ['styles'] | |
### SRC: SCRIPTS ### | |
# compile, bundle and minify scripts | |
# see: https://medium.com/@sogko/gulp-browserify-the-gulp-y-way-bb359b3f9623 | |
gulp.task 'scripts', ['clean:scripts', 'lint'], -> | |
browserified = transform (filename) -> | |
browserify | |
entries: filename | |
extensions: ['.coffee'] | |
debug: true | |
.bundle() | |
gulp | |
.src "#{paths.src}/scripts/index.coffee" | |
.pipe plumber handleError | |
.pipe browserified | |
.pipe gulpIf PROD, uglify opts.uglify | |
# .pipe gulpIf PROD, rev() | |
.pipe rename | |
extname: '.min.js' | |
.pipe size opts.size | |
.pipe gulp.dest "#{paths.dist}/scripts" | |
# .pipe gulpIf PROD, rev.manifest opts.rev | |
# .pipe gulpIf PROD, gulp.dest paths.root | |
# clean compiled scripts | |
gulp.task 'clean:scripts', (done) -> | |
del "#{paths.dist}/scripts/**/*.*", done | |
# watch scripts | |
gulp.task 'watch:scripts', -> | |
gulp.watch "#{paths.src}/scripts/**/*.coffee", ['scripts', browserSync.reload] | |
### SRC: IMAGES ### | |
# compress images | |
# see: https://github.com/sindresorhus/gulp-imagemin | |
gulp.task 'images', -> | |
gulp | |
.src "images/**", | |
cwd: "#{paths.src}/**" | |
.pipe plumber handleError | |
.pipe cache 'images' | |
.pipe imageMin | |
progressive: true | |
svgoPlugins: [ | |
{ | |
removeViewBox: false | |
} | |
] | |
use: [ | |
pngCrush() | |
] | |
.pipe gulp.dest paths.dist | |
# clean image output | |
gulp.task 'clean:images', (done) -> | |
del "#{paths.dist}/images/**/*.*", done | |
# watch images | |
gulp.task 'watch:images', -> | |
gulp.watch "#{paths.src}/images/**/*", ['images', browserSync.reload] | |
### SRC: ICONS ### | |
# SVG icon sprite | |
# see: http://css-tricks.com/svg-sprites-use-better-icon-fonts/ | |
gulp.task 'icons', -> | |
gulp | |
.src "#{paths.src}/icons/**/*.svg" | |
.pipe plumber handleError | |
.pipe svgSprite | |
shape: | |
id: | |
generator: 'icon-' | |
mode: | |
symbol: | |
inline: true | |
example: DEV and { dest: 'example/icons.html' } | |
dest: 'svg' | |
sprite: 'icons.svg' | |
.pipe gulp.dest paths.dist | |
# clean icon output | |
gulp.task 'clean:icons', (done) -> | |
del "#{paths.dist}/icons/**/*.*", done | |
# watch icons | |
gulp.task 'watch:icons', -> | |
gulp.watch "#{paths.src}/icons/**/*", ['jade-html', 'jade-js', browserSync.reload] | |
### SRC: JADE (TO JS) ### | |
# compile Jade templates to JS | |
# see: https://github.com/muraken720/nancle/blob/master/gulpfile.coffee | |
# TODO: find/request (or build) gulp-templatizer (stream support) | |
# TODO: don't compile back into src/ (seems wrong) | |
# TODO: can we replace this with gulp-jade compile to JS? (see: https://www.npmjs.com/package/gulp-jade) | |
# TODO: concat this with other scripts | |
# TODO: provide service for manifest URLs | |
gulp.task 'jade-js', ['icons'], -> | |
templatizer "#{paths.src}/jade/templates/js", "#{paths.src}/scripts/!tmpl.js" | |
# clean rendered Jade file | |
gulp.task 'clean:jade-js', (done) -> | |
del "#{paths.src}/scripts/!tmpl.js", done | |
# watch Jade files | |
gulp.task 'watch:jade-js', -> | |
gulp.watch [ | |
"#{paths.src}/jade/layouts/js/**/*.jade" | |
"#{paths.src}/jade/templates/js/**/*.jade" | |
], ['jade-js', 'scripts', browserSync.reload] | |
### SRC: JADE (TO HTML) ### | |
# render Jade to HTML | |
# TODO: provide service for manifest URLs | |
gulp.task 'jade-html', ['icons'], -> | |
# if PROD | |
# manifest = JSON.parse fs.readFileSync "#{paths.root}/rev-manifest.json", 'utf8' | |
gulp | |
.src "*.jade", | |
cwd: "#{paths.src}/jade/pages/**" | |
.pipe plumber handleError | |
.pipe cache 'jade-html' | |
.pipe jade _.merge {}, opts.jade, | |
locals: | |
# script: if manifest? then "scripts/#{manifest['index.coffee']}" else 'scripts/index.min.js' | |
# style: if manifest? then "styles/#{manifest['index.css']}" else 'styles/index.min.css' | |
script: 'scripts/index.min.js' | |
style: 'styles/index.min.css' | |
# .pipe htmlify() # add data- prefixes to non-HTML5-valid attributes | |
.pipe gulp.dest paths.dist | |
# clean rendered Jade files | |
gulp.task 'clean:jade-html', (done) -> | |
del "#{paths.dist}/*.html", done | |
# watch Jade files | |
gulp.task 'watch:jade-html', -> | |
gulp.watch [ | |
"#{paths.src}/jade/layouts/html/**/*.jade" | |
"#{paths.src}/jade/mixins/**/*.jade" | |
"#{paths.src}/jade/pages/**/*.jade" | |
"#{paths.src}/jade/svg/**/*.jade" | |
"#{paths.src}/icons/**/*.jade" | |
], ['jade-html', browserSync.reload] | |
### SRC: ANGULAR VIEWS ### | |
# render Angular views from Jade | |
gulp.task 'ng-views', -> | |
gulp | |
.src "*.jade", | |
cwd: "#{paths.src}/jade/views/**" | |
.pipe plumber handleError | |
.pipe cache 'ng-views' | |
.pipe jade opts.jade | |
# .pipe htmlify() # add data- prefixes to non-HTML5-valid attributes | |
.pipe gulp.dest "#{paths.dist}/views" | |
# clean Angular view output | |
gulp.task 'clean:ng-views', -> | |
del "#{paths.dist}/views/**/*.*", done | |
# watch Angular views | |
gulp.task 'watch:ng-views', -> | |
gulp.watch [ | |
"#{paths.src}/jade/views/**/*.jade" | |
"#{paths.src}/jade/partials/**/*.jade" | |
], ['ng-views', browserSync.reload] | |
### SRC: ANGULAR TEMPLATES ### | |
# render Angular templates from Jade | |
gulp.task 'ng-html', -> | |
gulp | |
.src "*.jade", | |
cwd: "#{paths.src}/jade/templates/html/**" | |
.pipe plumber handleError | |
.pipe cache 'ng-html' | |
.pipe jade opts.jade | |
# .pipe htmlify() # add data- prefixes to non-HTML5-valid attributes | |
# .pipe templateCache() # convert to JS strings and place in Angular template cache # TODO: figure this out (see: http://david.nowinsky.net/gulp-book/example/angular-templates.html) | |
.pipe gulp.dest "#{paths.dist}/templates" | |
# clean Angular template output | |
gulp.task 'clean:ng-html', -> | |
del "#{paths.dist}/templates/**/*.*", done | |
# watch Angular templates | |
gulp.task 'watch:ng-html', -> | |
gulp.watch "#{paths.src}/jade/templates/html/**/*.jade", ['ng-html', browserSync.reload] | |
### CORE TASKS ### | |
# development build & watch | |
gulp.task 'dev', buildTasks, -> | |
gulp.run [ | |
'hobo' | |
'serve' | |
'watch' | |
] | |
# production build | |
gulp.task 'prod', buildTasks, -> | |
gulp.run 'hobo' | |
### MAIN CLI TASKS ### | |
# build: call with 'gulp build' on command line | |
# use 'gulp build --prod' to prepare assets for production use (minify, etc.) | |
gulp.task 'build', ['clean'], -> | |
gulp.run 'prod' | |
# develop: call with 'gulp' on command line | |
gulp.task 'default', ['clean'], -> | |
gulp.run 'dev' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment