Skip to content

Instantly share code, notes, and snippets.

@nickeddy
Last active August 29, 2015 14:04
Show Gist options
  • Save nickeddy/18eac2d7aff4ba398933 to your computer and use it in GitHub Desktop.
Save nickeddy/18eac2d7aff4ba398933 to your computer and use it in GitHub Desktop.
var gulp = require('gulp'),
gutil = require('gulp-util');
var ngmin = require('gulp-ng-annotate'),
inject = require('gulp-inject'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
clean = require('gulp-rimraf'),
watch = require('gulp-watch'),
crypto = require('crypto'),
rename = require('gulp-rename'),
fs = require('fs'),
templateCache = require('gulp-angular-templatecache'),
lodash = require('lodash'),
minifyCSS = require('gulp-minify-css'),
filesize = require('gulp-filesize'),
es = require('event-stream'),
jsdoc = require('gulp-jsdoc'),
moment = require('moment'),
path = require('path');
var src_dir = 'src/';
var assets_dir = 'assets/';
var dependencies = [
assets_dir + 'js/dependencies/lodash.min.js',
assets_dir + 'js/dependencies/moment.min.js',
assets_dir + 'js/angular.min.js',
assets_dir + 'js/restangular.min.js',
assets_dir + 'js/angular-ui-router.min.js',
];
var css = [
src_dir + 'css/bootstrap.min.css',
src_dir + 'css/site.css',
];
var angularjs = [
src_dir + 'angular/modules.js',
src_dir + 'angular/services/*.js',
src_dir + 'angular/services/**/*.js',
src_dir + 'angular/factories/*.js',
src_dir + 'angular/factories/**/*.js',
src_dir + 'angular/filters/*.js',
src_dir + 'angular/filters/**/*.js',
src_dir + 'angular/directives/*.js',
src_dir + 'angular/directives/**/*.js',
src_dir + 'angular/controllers/*.js',
src_dir + 'angular/controllers/**/*.js',
src_dir + 'angular/states.js',
];
var partials = [
src_dir + 'partials/*.html',
src_dir + 'partials/**/*.html',
];
var index = src_dir + 'index.html';
var index_dest = assets_dir;
var module_name = 'ng.cms';
var jsChecksum, templateChecksum, cssChecksum;
var startTime, endTime;
var TARGET_TYPES = ['html', 'jade', 'slm', 'jsx'];
var IMAGES = ['jpeg', 'jpg', 'png', 'gif'];
var DEFAULT_TARGET = TARGET_TYPES[0];
var transform = module.exports = exports = function(filepath, i, length, sourceFile, targetFile) {
var type;
filepath = filepath.split(assets_dir)[1];
if (targetFile && targetFile.path) {
var ext = path.extname(targetFile.path).slice(1);
type = typeFromExt(ext);
}
if (!isTargetType(type)) {
type = DEFAULT_TARGET;
}
var func = transform[type];
if (func) {
return func.apply(transform, arguments);
}
};
/**
* Options
*/
transform.selfClosingTag = false;
/**
* Transform functions
*/
TARGET_TYPES.forEach(function(targetType) {
transform[targetType] = function(filepath) {
var ext = path.extname(filepath).slice(1);
var type = typeFromExt(ext);
var func = transform[targetType][type];
if (func) {
return func.apply(transform[targetType], arguments);
}
};
});
transform.html.css = function(filepath) {
return '<link rel="stylesheet" href="' + filepath + '"' + end();
};
transform.html.js = function(filepath) {
return '<script src="' + filepath + '"></script>';
};
transform.html.html = function(filepath) {
return '<link rel="import" href="' + filepath + '"' + end();
};
transform.html.coffee = function(filepath) {
return '<script type="text/coffeescript" src="' + filepath + '"></script>';
};
transform.html.image = function(filepath) {
return '<img src="' + filepath + '"' + end();
};
transform.jade.css = function(filepath) {
return 'link(rel="stylesheet", href="' + filepath + '")';
};
transform.jade.js = function(filepath) {
return 'script(src="' + filepath + '")';
};
transform.jade.html = function(filepath) {
return 'link(rel="import", href="' + filepath + '")';
};
transform.jade.coffee = function(filepath) {
return 'script(type="text/coffeescript", src="' + filepath + '")';
};
transform.jade.image = function(filepath) {
return 'img(src="' + filepath + '")';
};
transform.slm.css = function(filepath) {
return 'link rel="stylesheet" href="' + filepath + '"';
};
transform.slm.js = function(filepath) {
return 'script src="' + filepath + '"';
};
transform.slm.html = function(filepath) {
return 'link rel="import" href="' + filepath + '"';
};
transform.slm.coffee = function(filepath) {
return 'script type="text/coffeescript" src="' + filepath + '"';
};
transform.slm.image = function(filepath) {
return 'img src="' + filepath + '"';
};
/**
* Transformations for jsx is like html
* but always with self closing tags, invalid jsx otherwise
*/
Object.keys(transform.html).forEach(function(type) {
transform.jsx[type] = function() {
var originalOption = transform.selfClosingTag;
transform.selfClosingTag = true;
var result = transform.html[type].apply(transform.html, arguments);
transform.selfClosingTag = originalOption;
return result;
};
});
function end() {
return transform.selfClosingTag ? ' />' : '>';
}
function typeFromExt(ext) {
ext = ext.toLowerCase();
if (isImage(ext)) {
return 'image';
}
return ext;
}
function isImage(ext) {
return IMAGES.indexOf(ext) > -1;
}
function isTargetType(type) {
if (!type) {
return false;
}
return TARGET_TYPES.indexOf(type) > -1;
}
gulp.task('notabs', function() {
startTime = moment();
return gulp.src(angularjs)
.pipe(es.through(function(data) {
var fileData = String(data.contents);
if (fileData.indexOf('\t') !== -1) {
gutil.log(gutil.colors.bgRed('!!!!!!!!!!!!!!!!!!'));
gutil.log(gutil.colors.bgRed('!!!!!!!!!!!!!!!!!!'));
gutil.log(gutil.colors.bgRed('Don\'t use tabs!!!'));
gutil.log(gutil.colors.bgMagenta(data.path));
gutil.log(gutil.colors.bgRed('Please use two or four spaces.'));
gutil.log(gutil.colors.bgRed('!!!!!!!!!!!!!!!!!!'));
gutil.log(gutil.colors.bgRed('!!!!!!!!!!!!!!!!!!'));
}
}));
});
gulp.task('clean', ['notabs'], function() {
gutil.log(gutil.colors.bgRed('Cleaning ' + assets_dir + 'dist folder.'));
return gulp.src(['templates/dist', assets_dir + 'dist/app.min.js', assets_dir + 'dist/templates.js', assets_dir + 'css/dist/app.min.css'], {
read: false
})
.pipe(clean());
});
gulp.task('cleanbuild', ['inject'], function() {
gutil.log(gutil.colors.bgRed('Cleaning ' + assets_dir + 'dist folder after build.'));
gulp.src([assets_dir + 'dist/app.min.js', assets_dir + 'dist/templates.js', assets_dir + 'css/dist/app.min.css'], {
read: false
})
.pipe(clean());
endTime = moment();
var t = moment.duration(endTime.diff(startTime));
gutil.log(gutil.colors.bgBlue('ELAPSED TIME: ' + t.as('milliseconds') + ' milliseconds.'));
});
gulp.task('minify', ['minifyJS', 'minifyCSS']);
gulp.task('minifyJS', ['templates'], function() {
gutil.log(gutil.colors.bgYellow('Building app.min.js.'));
return gulp.src(angularjs)
.pipe(ngmin({
add: true,
}))
.pipe(gutil.env.type === 'production' ? uglify() : gutil.noop())
.pipe(concat('app.min.js'))
.pipe(gulp.dest(assets_dir + 'dist'));
});
gulp.task('minifyCSS', ['minifyJS'], function() {
gutil.log(gutil.colors.bgYellow('Building app.min.css.'));
return gulp.src(css)
.pipe(gutil.env.type === 'production' ? minifyCSS() : gutil.noop())
.pipe(concat('app.min.css'))
.pipe(gulp.dest(assets_dir + 'css/dist'));
});
var getChecksum = function(file) {
var hash = crypto.createHash('SHA256');
hash.update(file);
var h = hash.digest('hex').substr(0, 16);
return h;
};
gulp.task('templates', ['clean'], function() {
gutil.log(gutil.colors.bgYellow('Building templates.js.'));
return gulp.src(partials)
.pipe(templateCache('templates.js', {
standalone: true,
}))
.pipe(gutil.env.type === 'production' ? uglify() : gutil.noop())
.pipe(gulp.dest(assets_dir + 'dist'));
});
gulp.task('rename', ['renameJavascript', 'renameTemplates', 'renameCSS']);
gulp.task('renameCSS', ['renameTemplates'], function() {
var cssfile = fs.readFileSync(assets_dir + 'css/dist/app.min.css');
cssChecksum = getChecksum(cssfile);
gutil.log(gutil.colors.bgGreen('Got checksum ' + cssChecksum + ' for app.min.css.'));
return gulp.src(assets_dir + 'css/dist/app.min.css')
.pipe(rename(cssChecksum + '.min.css'))
.pipe(gulp.dest(assets_dir + 'css/dist'))
.pipe(filesize());
});
gulp.task('renameTemplates', ['renameJavascript'], function() {
var tplfile = fs.readFileSync(assets_dir + 'dist/templates.js');
templateChecksum = getChecksum(tplfile);
gutil.log(gutil.colors.bgGreen('Got checksum ' + templateChecksum + ' for templates.js.'));
return gulp.src(assets_dir + 'dist/templates.js')
.pipe(rename(templateChecksum + '.tpl.min.js'))
.pipe(gulp.dest(assets_dir + 'dist'))
.pipe(filesize());
});
gulp.task('renameJavascript', ['templates', 'minify'], function() {
var file = fs.readFileSync(assets_dir + 'dist/app.min.js');
jsChecksum = getChecksum(file);
gutil.log(gutil.colors.bgGreen('Got checksum ' + jsChecksum + ' for app.min.js.'));
return gulp.src(assets_dir + 'dist/app.min.js')
.pipe(rename(jsChecksum + '.min.js'))
.pipe(gulp.dest(assets_dir + 'dist'))
.pipe(filesize());
});
gulp.task('inject', ['rename'], function() {
gutil.log(gutil.colors.bgYellow('Injecting into base.html.'));
return gulp.src(index)
.pipe(inject(gulp.src(dependencies, {
read: false,
}), {
transform: transform,
starttag: '<!-- inject:deps:{{ext}} -->',
}))
.pipe(inject(gulp.src([assets_dir + 'dist/' + templateChecksum + '.tpl.min.js', assets_dir + 'dist/' + jsChecksum + '.min.js'], {
read: false,
}), {
transform: transform,
starttag: '<!-- inject:angular:{{ext}} -->',
}))
.pipe(inject(gulp.src([assets_dir + 'css/dist/' + cssChecksum + '.min.css'], {
read: false,
}), {
transform: transform,
starttag: '<!-- inject:css:{{ext}} -->',
}))
.pipe(gulp.dest(index_dest));
});
gulp.task('watch', function() {
gulp.watch([src_dir + '*.js', src_dir + '*.html', src_dir + '*.css', src_dir + '**/*.js', src_dir + '**/*.css', src_dir + '**/*.html'], ['notabs', 'clean', 'templates', 'minify', 'rename', 'inject', 'cleanbuild']);
gulp.watch('templates/base.html', ['notabs', 'clean', 'templates', 'minify', 'rename', 'inject', 'cleanbuild']);
});
gulp.task('default', ['notabs', 'clean', 'templates', 'minify', 'rename', 'inject', 'cleanbuild']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment