germ
Version:
Opinionated boilerplate to unify server and client side code
264 lines (222 loc) • 7.67 kB
JavaScript
;
var gulp = require('gulp')
, fs = require('fs')
, path = require('path')
, gutil = require('gulp-util')
, plugins = require('gulp-load-plugins')()
, webpack = require("webpack")
, runSequence = require('run-sequence')
, browserSync = require('browser-sync')
, spawn = require('child_process').spawn
, reload = browserSync.reload;
var config = {
scssPath: ['assets/styles/**/*.scss', '!assets/styles/**/_*.scss'],
lessPath: ['assets/styles/**/*.less', '!assets/styles/**/_*.less'],
cssPath: ['assets/styles/**/*.css'],
autoprefixer: {
browsers:["last 1 version", "> 1%", "ie 8", "ie 7"],
map:false
},
webpack: {
webpackers:[]
}
}
// ###############################################
// CODING STANDARDS
// ###############################################
gulp.task('jshint', function () {
return gulp.src('src/**/*.js')
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('jshint-stylish'))
.pipe(plugins.jshint.reporter('fail'))
});
// ###############################################
// CODE ASSETS
// ###############################################
gulp.task('client:js', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(plugins.sourcemaps.init())
.pipe(plugins.concat('all.js', {newLine: ';'}))
.pipe(plugins.sourcemaps.write())
.pipe(gulp.dest('public/js'))
.pipe(plugins.size({showFiles:true}))
.pipe(plugins.uglify({outSourceMap:true}))
//.pipe(plugins.sourcemaps.write())
.pipe(plugins.rename({suffix:'.min'}))
.pipe(gulp.dest('public/js'))
.pipe(plugins.size({showFiles:true}))
});
gulp.task('react:components', function () {
return gulp.src('assets/components/**/*.jsx')
.pipe(plugins.insert.prepend('var React = require(\'react\');'))
.pipe(plugins.react())
.pipe(gulp.dest('src/components'));
});
// ###############################################
// ASSET PIPELINE
// ###############################################
gulp.task('images', function () {
return gulp.src('assets/images/**/*')
.pipe(plugins.cache(plugins.imagemin({
progressive: true,
interlaced: true
})))
.pipe(gulp.dest('public/images'))
.pipe(reload({stream: true, once:true}))
.pipe(plugins.size({showFiles:true}));
});
gulp.task('images:full', function () {
// we should use ImageOptim-CLI because it has the best compression
// or gulp-tinypng is great for png
});
gulp.task('images:spirits', function () {
// look
});
gulp.task('images:glyphs', function () {
// gulp-iconfont
});
// ###############################################
// STYLES ASSETS (css, less, sass files)
// ###############################################
function minifyCSS(chain) {
return chain
.pipe(plugins.rename({suffix:'.min'}))
.pipe(plugins.newer({dest:'public/css'}))
.pipe(plugins.size({showFiles:true}))
.pipe(plugins.minifyCss({keepBreaks:true, keepSpecialComments:'*', noAdvanced:false})) // this about using CSSO could be better
.pipe(plugins.replace(/\/\*\!/g, '/*'))
.pipe(plugins.size({showFiles:true}))
.pipe(gulp.dest('public/css'))
.pipe(reload({stream: true, once:true}));
}
gulp.task('styles:scss', function () {
return minifyCSS(
gulp.src(config.scssPath)
//.pipe(plugins.newer({dest:'public/css', ext:'.css'}))
.pipe(plugins.sass({
sourceComments: 'map',
sourceMap: 'sass',
style: 'compact',
errLogToConsole: true
}))
.pipe(plugins.autoprefixer(config.autoprefixer))
.pipe(gulp.dest('public/css'))
);
});
gulp.task('styles:less', function () {
return minifyCSS(
gulp.src(config.lessPath)
.pipe(plugins.newer({dest:'public/css', ext:'.css'}))
.pipe(plugins.autoprefixer(config.autoprefixer))
.pipe(plugins.less({
sourceMap: true,
ieCompat: true,
paths: [ path.join(__dirname, 'assets', 'styles') ]
}))
.pipe(gulp.dest('public/css'))
);
});
gulp.task('styles:css', function () {
return minifyCSS(
gulp.src(config.cssPath)
.pipe(plugins.newer({dest:'public/css'}))
.pipe(plugins.autoprefixer(config.autoprefixer))
.pipe(gulp.dest('public/css'))
);
});
// ###############################################
// BUILD CLIENT-SIDE PACKAGE
// ###############################################
gulp.task('app:bundle:setup', function () {
config.webpack.webpackers = [];
return gulp.src(['assets/**/*.webpack', 'src/**/*.webpack'])
//.pipe(plugins.newer({dest:'public/js', ext:'.js'}))
.pipe(plugins.tap(function(file, t) {
delete require.cache[file.path];
var webpackConfig = require(file.path);
//webpackConfig.debug = true;
webpackConfig.context = path.join(__dirname, 'src');
if(!webpackConfig.output) {
webpackConfig.output = {
path: path.join(__dirname, 'public', 'js'),
filename: path.basename(file.path).replace('.webpack', '.js')
}
}
config.webpack.webpackers.push(webpack(webpackConfig));
}));
});
gulp.task('app:bundle', ['react:components'], function (next) {
var cbcount = config.webpack.webpackers.length;
for(var i in config.webpack.webpackers) {
config.webpack.webpackers[i].run(function(err, stats) {
gutil.log("[app:bundle]", stats.toString({
colors: true
}));
if(--cbcount === 0) {
if(err) next(new gutil.PluginError("app:bundle", err));
else next();
return;
}
});
}
});
// ###############################################
// 3-PARTY DEPENDENCIES
// ###############################################
gulp.task('bower:install', function() {
return plugins.bowerFiles().pipe(gulp.dest('assets/vender'));
});
gulp.task('bower:copy', ['bower:install'], function() {
// copy the files from our bower into the right locations
// maybe we need to copy all *.js-> /js *.css-> /css *.font -> /fonts etc into public
});
// ###############################################
// SERVER
// ###############################################
var node;
gulp.task('run', function(next) {
if (node) node.kill();
node = spawn(path.join(__dirname, 'bin', 'germ'), ['-c', 'local'], {cwd:__dirname, stdio:'inherit'});
node.on('close', function (code) {
if (code === 8) {
gutil.log('Error detected, waiting for changes...', code);
}
});
node.on('error', function (code) {
gutil.log('Error detected:', arguments);
});
//reload({stream:true});
next();
});
// clean up if an error goes unhandled.
process.on('exit', function() {
if (node) node.kill()
});
// ###############################################
// psi (google page speed test)
// ###############################################
// ###############################################
// TARGETS
// ###############################################
gulp.task('default', function(next) {
runSequence('build', ['watch'], next);
});
gulp.task('build', function (next) {
runSequence(/*'bower:copy',*/ ['styles:less', 'styles:scss', 'styles:css'], /*'jshint',*/ 'app:bundle:setup','app:bundle', next);
});
gulp.task('watch', ['run'], function (next) {
browserSync.init(null, {
proxy: "http://127.0.0.1:8080",
notify: false
});
gulp.watch(config.lessPath[0], ['styles:less']);
gulp.watch(config.scssPath[0], ['styles:scss']);
gulp.watch(config.cssPath[0], ['styles:css']);
gulp.watch('assets/images/**/*', ['images']);
gulp.watch('assets/components/**/*.jsx', ['app:bundle']);
gulp.watch(['./src/**/*.js'], function(next) {
return gulp.run('run');
runSequence('run', next);
});
gulp.watch(['bower.json'], ['bower:copy']);
})