import browserify from 'browserify'; import browserSync from 'browser-sync'; import duration from 'gulp-duration'; import es from 'event-stream'; import exorcist from 'exorcist'; import gulp from 'gulp'; import gutil from 'gulp-util'; import inject from 'gulp-inject'; import jade from 'gulp-jade'; import less from 'gulp-less'; import notifier from 'node-notifier'; import path from 'path'; import prefix from 'gulp-autoprefixer'; import rev from 'gulp-rev'; import source from 'vinyl-source-stream'; import sourcemaps from 'gulp-sourcemaps'; import streamify from 'gulp-streamify'; import stylus from 'gulp-stylus'; import transform from 'vinyl-transform'; import uglify from 'gulp-uglify'; import watch from 'gulp-watch'; import watchify from 'watchify'; /*eslint "no-process-env":0 */ const production = process.env.NODE_ENV === 'production'; const config = { source: './src', destination: './public', scripts: { source: './src/js/main.js', destination: './public/js/', extensions: ['.jsx'], filename: 'bundle.js' }, templates: { source: './src/*.jade', watch: './src/*.jade', destination: './public/', revision: './public/**/*.html' }, styles: { source: './src/styles/style.styl', watch: './src/styles/**/*.styl', icons: './src/styles/icons.less', destination: './public/css/' }, assets: { source: ['./src/assets/**/*.*', './node_modules/font-awesome/fonts*/*.*'], watch: './src/assets/**/*.*', destination: './public/' }, inject: { resources: ['./public/**/*.css', './public/**/*.js'] } }; const browserifyConfig = { entries: [config.scripts.source], extensions: config.scripts.extensions, debug: !production, cache: {}, packageCache: {} }; function handleError(err) { gutil.log(err.message); gutil.beep(); notifier.notify({ title: 'Compile Error', message: err.message }); return this.emit('end'); } gulp.task('scripts', () => { let pipeline = browserify(browserifyConfig) .bundle() .on('error', handleError) .pipe(source(config.scripts.filename)); if(production) { pipeline = pipeline .pipe(streamify(uglify())) .pipe(streamify(rev())); } else { pipeline = pipeline.pipe(transform(() => { return exorcist(path.join(config.scripts.destination, config.scripts.filename) + '.map'); })); } return pipeline.pipe(gulp.dest(config.scripts.destination)); }); gulp.task('templates', ['styles', 'scripts'], () => { const resources = gulp.src(config.inject.resources, {read: false}); const pipeline = gulp.src(config.templates.source) .pipe(jade({ pretty: !production })) .on('error', handleError) .pipe(inject(resources, {ignorePath: 'public', removeTags: true})) .pipe(gulp.dest(config.templates.destination)); if(production) { return pipeline; } return pipeline.pipe(browserSync.reload({ stream: true })); }); gulp.task('styles', () => { let pipeline = gulp.src(config.styles.source); if(!production) { pipeline = pipeline.pipe(sourcemaps.init()); } const icons = gulp.src(config.styles.icons) .pipe(less()); pipeline = es.merge(icons, pipeline.pipe(stylus({ 'include css': true, paths: ['node_modules', path.join(__dirname, config.source)], compress: production }))) .on('error', handleError) .pipe(prefix('last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7')); if(production) { pipeline = pipeline.pipe(rev()); } else { pipeline = pipeline.pipe(sourcemaps.write('.')); } pipeline = pipeline.pipe(gulp.dest(config.styles.destination)); if(production) { return pipeline; } return pipeline.pipe(browserSync.stream({ match: '**/*.css' })); }); gulp.task('assets', () => { return gulp.src(config.assets.source) .pipe(gulp.dest(config.assets.destination)); }); gulp.task('server', () => { return browserSync({ open: false, port: 9001, notify: false, ghostMode: false, server: { baseDir: config.destination } }); }); gulp.task('watch', () => { ['templates', 'styles', 'assets'].forEach((watched) => { watch(config[watched].watch, () => { gulp.start(watched); }); }); const bundle = watchify(browserify(browserifyConfig)); bundle.on('update', () => { const build = bundle.bundle() .on('error', handleError) .pipe(source(config.scripts.filename)); build .pipe(transform(() => { return exorcist(config.scripts.destination + config.scripts.filename + '.map'); })) .pipe(gulp.dest(config.scripts.destination)) .pipe(duration('Rebundling browserify bundle')) .pipe(browserSync.reload({stream: true})); }).emit('update'); }); gulp.task('build', ['styles', 'assets', 'scripts', 'templates']); gulp.task('default', ['styles', 'assets', 'templates', 'watch', 'server']);