-
Star
(202)
You must be signed in to star a gist -
Fork
(34)
You must be signed in to fork a gist
-
-
Save mlouro/8886076 to your computer and use it in GitHub Desktop.
'use strict'; | |
var gulp = require('gulp'); | |
var gutil = require('gulp-util'); | |
var del = require('del'); | |
var uglify = require('gulp-uglify'); | |
var gulpif = require('gulp-if'); | |
var exec = require('child_process').exec; | |
var notify = require('gulp-notify'); | |
var buffer = require('vinyl-buffer'); | |
var argv = require('yargs').argv; | |
// sass | |
var sass = require('gulp-sass'); | |
var postcss = require('gulp-postcss'); | |
var autoprefixer = require('autoprefixer-core'); | |
var sourcemaps = require('gulp-sourcemaps'); | |
// BrowserSync | |
var browserSync = require('browser-sync'); | |
// js | |
var watchify = require('watchify'); | |
var browserify = require('browserify'); | |
var source = require('vinyl-source-stream'); | |
// image optimization | |
var imagemin = require('gulp-imagemin'); | |
// linting | |
var jshint = require('gulp-jshint'); | |
var stylish = require('jshint-stylish'); | |
// testing/mocha | |
var mocha = require('gulp-mocha'); | |
// gulp build --production | |
var production = !!argv.production; | |
// determine if we're doing a build | |
// and if so, bypass the livereload | |
var build = argv._.length ? argv._[0] === 'build' : false; | |
var watch = argv._.length ? argv._[0] === 'watch' : true; | |
// ---------------------------- | |
// Error notification methods | |
// ---------------------------- | |
var beep = function() { | |
var os = require('os'); | |
var file = 'gulp/error.wav'; | |
if (os.platform() === 'linux') { | |
// linux | |
exec("aplay " + file); | |
} else { | |
// mac | |
console.log("afplay " + file); | |
exec("afplay " + file); | |
} | |
}; | |
var handleError = function(task) { | |
return function(err) { | |
beep(); | |
notify.onError({ | |
message: task + ' failed, check the logs..', | |
sound: false | |
})(err); | |
gutil.log(gutil.colors.bgRed(task + ' error:'), gutil.colors.red(err)); | |
}; | |
}; | |
// -------------------------- | |
// CUSTOM TASK METHODS | |
// -------------------------- | |
var tasks = { | |
// -------------------------- | |
// Delete build folder | |
// -------------------------- | |
clean: function(cb) { | |
del(['build/'], cb); | |
}, | |
// -------------------------- | |
// Copy static assets | |
// -------------------------- | |
assets: function() { | |
return gulp.src('./client/assets/**/*') | |
.pipe(gulp.dest('build/assets/')); | |
}, | |
// -------------------------- | |
// HTML | |
// -------------------------- | |
// html templates (when using the connect server) | |
templates: function() { | |
gulp.src('templates/*.html') | |
.pipe(gulp.dest('build/')); | |
}, | |
// -------------------------- | |
// SASS (libsass) | |
// -------------------------- | |
sass: function() { | |
return gulp.src('./client/scss/*.scss') | |
// sourcemaps + sass + error handling | |
.pipe(gulpif(!production, sourcemaps.init())) | |
.pipe(sass({ | |
sourceComments: !production, | |
outputStyle: production ? 'compressed' : 'nested' | |
})) | |
.on('error', handleError('SASS')) | |
// generate .maps | |
.pipe(gulpif(!production, sourcemaps.write({ | |
'includeContent': false, | |
'sourceRoot': '.' | |
}))) | |
// autoprefixer | |
.pipe(gulpif(!production, sourcemaps.init({ | |
'loadMaps': true | |
}))) | |
.pipe(postcss([autoprefixer({browsers: ['last 2 versions']})])) | |
// we don't serve the source files | |
// so include scss content inside the sourcemaps | |
.pipe(sourcemaps.write({ | |
'includeContent': true | |
})) | |
// write sourcemaps to a specific directory | |
// give it a file and save | |
.pipe(gulp.dest('build/css')); | |
}, | |
// -------------------------- | |
// Browserify | |
// -------------------------- | |
browserify: function() { | |
var bundler = browserify('./client/js/index.js', { | |
debug: !production, | |
cache: {} | |
}); | |
// determine if we're doing a build | |
// and if so, bypass the livereload | |
var build = argv._.length ? argv._[0] === 'build' : false; | |
if (watch) { | |
bundler = watchify(bundler); | |
} | |
var rebundle = function() { | |
return bundler.bundle() | |
.on('error', handleError('Browserify')) | |
.pipe(source('build.js')) | |
.pipe(gulpif(production, buffer())) | |
.pipe(gulpif(production, uglify())) | |
.pipe(gulp.dest('build/js/')); | |
}; | |
bundler.on('update', rebundle); | |
return rebundle(); | |
}, | |
// -------------------------- | |
// linting | |
// -------------------------- | |
lintjs: function() { | |
return gulp.src([ | |
'gulpfile.js', | |
'./client/js/index.js', | |
'./client/js/**/*.js' | |
]).pipe(jshint()) | |
.pipe(jshint.reporter(stylish)) | |
.on('error', function() { | |
beep(); | |
}); | |
}, | |
// -------------------------- | |
// Optimize asset images | |
// -------------------------- | |
optimize: function() { | |
return gulp.src('./client/assets/**/*.{gif,jpg,png,svg}') | |
.pipe(imagemin({ | |
progressive: true, | |
svgoPlugins: [{removeViewBox: false}], | |
// png optimization | |
optimizationLevel: production ? 3 : 1 | |
})) | |
.pipe(gulp.dest('./client/assets/')); | |
}, | |
// -------------------------- | |
// Testing with mocha | |
// -------------------------- | |
test: function() { | |
return gulp.src('./client/**/*test.js', {read: false}) | |
.pipe(mocha({ | |
'ui': 'bdd', | |
'reporter': 'spec' | |
}) | |
); | |
}, | |
}; | |
gulp.task('browser-sync', function() { | |
browserSync({ | |
server: { | |
baseDir: "./build" | |
}, | |
port: process.env.PORT || 3000 | |
}); | |
}); | |
gulp.task('reload-sass', ['sass'], function(){ | |
browserSync.reload(); | |
}); | |
gulp.task('reload-js', ['browserify'], function(){ | |
browserSync.reload(); | |
}); | |
gulp.task('reload-templates', ['templates'], function(){ | |
browserSync.reload(); | |
}); | |
// -------------------------- | |
// CUSTOMS TASKS | |
// -------------------------- | |
gulp.task('clean', tasks.clean); | |
// for production we require the clean method on every individual task | |
var req = build ? ['clean'] : []; | |
// individual tasks | |
gulp.task('templates', req, tasks.templates); | |
gulp.task('assets', req, tasks.assets); | |
gulp.task('sass', req, tasks.sass); | |
gulp.task('browserify', req, tasks.browserify); | |
gulp.task('lint:js', tasks.lintjs); | |
gulp.task('optimize', tasks.optimize); | |
gulp.task('test', tasks.test); | |
// -------------------------- | |
// DEV/WATCH TASK | |
// -------------------------- | |
gulp.task('watch', ['assets', 'templates', 'sass', 'browserify', 'browser-sync'], function() { | |
// -------------------------- | |
// watch:sass | |
// -------------------------- | |
gulp.watch('./client/scss/**/*.scss', ['reload-sass']); | |
// -------------------------- | |
// watch:js | |
// -------------------------- | |
gulp.watch('./client/js/**/*.js', ['lint:js', 'reload-js']); | |
// -------------------------- | |
// watch:html | |
// -------------------------- | |
gulp.watch('./templates/**/*.html', ['reload-templates']); | |
gutil.log(gutil.colors.bgGreen('Watching for changes...')); | |
}); | |
// build task | |
gulp.task('build', [ | |
'clean', | |
'templates', | |
'assets', | |
'sass', | |
'browserify' | |
]); | |
gulp.task('default', ['watch']); | |
// gulp (watch) : for development and livereload | |
// gulp build : for a one off development build | |
// gulp build --production : for a minified production build |
+1
How do you deal with third-party styles and scripts (such as Twitter Bootstrap)? Do you put these files under client
directory?
@roganov, the third-party styles go into client/assets
and get copied over to the build directory.
@alexbw, the proxy is setup via browserSync's options, it's not in this gist, see https://github.com/lincolnloop/generator-frigate/blob/master/app/templates/_gulp.config.js#L44-L46. When proxyOptions.proxy is set, browserSync will just forward requests it can't handle over to the address you define there.
+1
nicely structured, well done. Thanks for sharing!
I had to comment out var req = build ? ['clean'] : [];
and replace it with var req = [];
on line 221, because for some reason gulp build
would stop right after clean
.
$ gulp build
autoprefixer-core was deprecated. Use autoprefixer package.
[01:17:14] Using gulpfile /code/gulpfile.js
[01:17:14] Starting 'clean'...
If anyone knows why or has a better fix, please help!
Hey! child_process
isn't recommended.
New implementation:
//...
let exec = require('gulp-exec');
let autoprefixer = require('gulp-autoprefixer'); // old autoprefixer-core
//...
let beep = function() {
let os = require('os');
let error = gulp.src('path/error.wav');
if (os.platform() === 'linux') {
error.pipe(exec('aplay <%= file.path %>'));
} else {
// mac
error.pipe(exec('afplay <%= file.path %>'));
}
};
//...
Many thanks for this ! Using it for everything now :D
Thanks for this. Did you make the package.json available?
I ran into the same problem as @Dovizu. Apparently new versions of del
have changed in how they handle the callback. Here's an improved clean
task which will run properly:
clean: function(callback) {
del(['build/']).then(function() {
callback();
});
}
So the SASS changes you gonna reload the browser instead of inject only changes ?
Awesome. Thanks.
Fantastic! You mentioned in a recent blog post that you access your site locally via port 8000. How are you configuring this proxy, and are you doing it in Vagrant?