Skip to content

Instantly share code, notes, and snippets.

@jaidetree
Last active August 29, 2015 14:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaidetree/59ac65db108b03ea08eb to your computer and use it in GitHub Desktop.
Save jaidetree/59ac65db108b03ea08eb to your computer and use it in GitHub Desktop.
var _ = require('underscore'),
browserifyAPI = require('browserify'),
BrowserifyFactory = {},
buffer = require('vinyl-buffer'),
filter = require('gulp-filter'),
fs = require('fs'),
glob = require('glob'),
gulp = require('gulp'),
gutil = require('gulp-util'),
inliner = require('gulp-mc-inline-css'),
jslint = require('gulp-jslint'),
jstify = require('jstify'),
minimist = require('minimist'),
path = require('path'),
paths = {
BASE: 'instevent/',
sources: {},
build: {},
watch: {},
jsPath: function (file) {
return this.APPJS + file;
},
mainPath: function(file) {
return this.MAIN + file;
},
staticPath: function (file) {
return this.STATIC + file;
}
},
rename = require('gulp-rename'),
source = require('vinyl-source-stream'),
sourcemaps = require('gulp-sourcemaps'),
spritesmith = require('gulp.spritesmith'),
streamify = require('gulp-streamify'),
sync = require('browser-sync'),
through = require('through2'),
transform = require('vinyl-transform'),
uglify = require('gulp-uglify'),
watchifyAPI = require('watchify');
paths.STATIC = paths.BASE + 'app/main/static/';
paths.APPJS = paths.BASE + 'app/main/js/';
paths.MAIN = paths.BASE + 'app/main/';
paths.sources.css = paths.STATIC + 'css/**/*.css';
paths.sources.djangoTemplates = paths.BASE + 'templates/**/*.html';
paths.sources.email = paths.BASE + 'templates/emails/**/*.source.html';
paths.sources.jsTemplates = paths.APPJS + 'templates/**/*.html';
paths.sources.js = paths.APPJS + 'app/**/*.js';
paths.sources.legacyJS = paths.STATIC + 'js/*/*.js';
paths.sources.sprites = paths.STATIC + '_sprites/*/*.png';
paths.sources.templates = [paths.sources.jsTemplates, paths.sources.djangoTemplates];
paths.build.js = paths.STATIC + 'js/build';
paths.watch.js = [paths.APPJS + '**/*.js', paths.sources.jsTemplates];
paths.watch.assets = [
paths.build.js + '/**/*.js',
paths.sources.legacyJS,
paths.sources.css
];
BrowserifyFactory = {
defaults: {
debug: true,
basedir: paths.jsPath('app'),
detectGlobals: false,
insertGlobals: false
},
create: function(method) {
return this[method]()
},
browserify: function(options) {
var opts = _.extend({}, this.defaults, options || {});
return browserifyAPI(opts)
.transform('jstify', { minifierOpts: false });
},
watchify: function() {
return watchifyAPI(this.browserify({
cache: {},
packageCache: {},
fullPaths: true
}));
}
};
function browserify() {
return through.obj(function(file, enc, next) {
var bundler = BrowserifyFactory.create('browserify', file, next);
bundler.add(file)
.on('bundle', function(arguments) {
gutil.log(gutil.colors.cyan('Browserifying'), gutil.colors.magenta(file.relative))
})
.bundle(function(err, res) {
if (!err) {
next(null, file);
}
})
.on('error', function(err) {
console.log("\n");
gutil.log(gutil.colors.bold.red('Browserify error:'), gutil.colors.bold.red(err.message + ' in ' + file.relative));
sync.notify('<span style="color:red;">Error: Browserify could not compile js.</span>', 6000);
})
.on('end', function() {
gutil.log(gutil.colors.green('Compiled'), gutil.colors.magenta(file.relative))
})
.pipe(source(file.relative))
.pipe(buffer())
});
}
function watchify() {
return through.obj(function(file, enc, next) {
var bundler = BrowserifyFactory.create('watchify');
console.log( bundler, file );
bundler.add(file)
.on('update', bundle);
function bundle() {
gutil.log(gutil.colors.cyan('Browserifying'), gutil.colors.magenta(file.relative))
return bundler.bundle()
.on('error', function(err) {
console.log("\n");
gutil.log(gutil.colors.bold.red('Browserify error:'), gutil.colors.bold.red(err.message + ' in ' + file.relative));
sync.notify('<span style="color:red;">Error: Browserify could not compile js.</span>', 6000);
})
.on('end', function() {
gutil.log(gutil.colors.green('Compiled'), gutil.colors.magenta(file.relative))
})
.pipe(source(file.relative))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.build.js));
}
next(null, file);
bundle();
});
}
// Task: Browserify
// Takes our js modules in the paths.sources.js and runs them through
// browserify, uglifies them, and generates sourcemaps.
gulp.task('browserify', function () {
return gulp.src(paths.sources.js)
.pipe(browserify())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.build.js))
.pipe(sync.reload({ stream: true, once: true }));
});
// Task: Browserify this
// Takes arguments to compile a single file
gulp.task('browserify-this', function() {
var opts = minimist(process.argv.slice(2)),
files = [],
bundle, i;
if (opts.module && !(opts.module instanceof Array)) {
opts.module = [opts.module];
}
for(i=0; i < opts.module.length; i++) {
gutil.log(gutil.colors.cyan('compiling module:'), gutil.colors.magenta(opts.module[i]));
opts.module[i] = paths.jsPath('app/**/*' + opts.module[i] + '.js');
}
gulp.src(opts.module)
.pipe(browserify())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.build.js))
.pipe(sync.reload({ stream: true, once: true }));
})
// Task: Email
// Takes our email templates with separated styles and inlines them
// through the mailchimp API
gulp.task('email', function () {
var config = require('./config.json');
gulp.src(paths.email)
.pipe(inliner(config.APIKEY))
.pipe(rename(function (path) {
path.basename = path.basename.replace('.source', '');
path.extname = '.email';
}))
.pipe(gulp.dest('instevent/templates/emails/build'));
});
// Task: Lint
// Takes a --module --js or --static argument to lint a file or series of files
gulp.task('lint', function () {
var opts = minimist(process.argv.slice(2)),
src = [];
if (!_.isArray(opts.file)) {
opts.file = [opts.file];
}
_.each(opts.file, function(fileName) {
var file = paths.jsPath(fileName);
if (!fs.existsSync(file)) {
gutil.log(gutil.colors.red('Could not find'), gutil.colors.magenta(file));
return;
}
gutil.log(gutil.colors.cyan('Linting:'), gutil.colors.magenta(file));
src.push(file);
}, this);
gulp.src(src)
.pipe(jslint({
browser: true,
node: true,
ass: true,
nomen: true,
regexp: true,
sloppy: true,
todo: true,
white: true,
indent: 4,
global: [
'require',
'DataBootstrap',
'CKEDITOR',
'define',
'Backbone',
'Braintree',
'google'
],
errorsOnly: true,
}))
.on('error', function() {
gutil.log(gutil.colors.cyan('Lint'), gutil.colors.magenta(src), gutil.colors.red('failed!'))
});
});
// Task: Watchify
gulp.task('watchify', function() {
gulp.src(paths.sources.js)
.pipe(watchify());
});
// Task: Watchify
// Allows us to compile browserify stuff then caches the files for
// even faster compiles the next time
// TODO: Refactor this and the browserify task to use the same
// implementation to reduce problems.
// gulp.task('watchify', function () {
// var watchifier = transform(function(filepath) {
// var filename = filepath.replace(path.join(__dirname, paths.APPJS, 'app'), '').slice(1),
// bundler = watchify(browserify(filepath, {
// debug: true,
// basedir: paths.jsPath('app'),
// paths: ['./node_modules', './' + paths.APPJS],
// cache: {}, packageCache: {}, fullPaths: true
// }));
// bundler.transform('jstify', { minifierOpts: false });
// bundler.on('update', function() {
// gutil.log(gutil.colors.cyan('File updated:'), gutil.colors.magenta(filename));
// rebundle();
// });
// function rebundle() {
// sync.notify('Compiling "<span style="color:magenta">' + filename + '</span>"...', 6000);
// return bundler.bundle()
// .on('error', function(err) {
// gutil.log('Browserify error: ', err.message);
// sync.notify('<span style="color: red;">Error: Browserify could not compile js.</span>', 6000);
// })
// .pipe(source(filename))
// .pipe(streamify(sourcemaps.init({ loadMaps: true })))
// .pipe(streamify(uglify()))
// .pipe(streamify(sourcemaps.write('./')))
// .pipe(gulp.dest(paths.build.js));
// }
// return gulp.src(filepath);
// });
// gulp.src(paths.sources.js)
// .pipe(watchifier);
// });
// Task: Watch
// Runs our watch tasks to run tasks based on changed files
// Uses browsersync to update the browser with changes
gulp.task('watch', ['watchify'], function () {
try {
sync.init(paths.watch.assets, {
open: false,
proxy: 'localhost:8080'
});
} catch (err) {
gutil.log(err);
}
});
// Task: Watch This
// Works like watch except uses command line arguments to determine
// what to watch to avoid too many files errors.
gulp.task('watch-this', ['watchify'], function() {
var assets = paths.watch.assets,
opts = minimist(process.argv.slice(2)),
path = paths.BASE + 'templates/' + opts.dir + '/**/*.html';
gutil.log(gutil.colors.cyan('Watching directory:'), gutil.colors.magenta(path));
assets.push(path);
try {
sync.init(assets, {
open: false,
proxy: 'localhost:8080'
});
} catch (err) {
gutil.log(err);
}
});
// Task: Sprite
// Runs the sprite images through spritesmith to generate a single sprite
// image and the SASS file.
gulp.task('sprite', function () {
var spriteData = gulp.src(paths.sources.sprites)
.pipe(spritesmith({
imgName: 'sprites.png',
cssName: '_sprites.scss',
imgPath: '../images/sprites/sprites.png',
cssFormat: 'css',
cssOpts: {
cssClass: function (item) {
var name = item.name;
name = name.replace(/\_/g, '--');
return '%' + name;
}
}
}));
spriteData.img
.pipe(gulp.dest(paths.staticPath('images/sprites')));
spriteData.css
.pipe(gulp.dest(paths.staticPath('sass/ui/')));
});
// Task: Default
// Runs whichever tasks when you run 'gulp' in the console
gulp.task('default', ['watch']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment