Skip to content

Instantly share code, notes, and snippets.

@ghidinelli
Last active October 4, 2018 11:41
Show Gist options
  • Save ghidinelli/e9806063ddbfa74bed7e to your computer and use it in GitHub Desktop.
Save ghidinelli/e9806063ddbfa74bed7e to your computer and use it in GitHub Desktop.
Creating rev-manifest file after gulp-rev runs in parallel
// I have a bunch of style/script tasks running in parallel which
// were overwriting or garbling my rev-manifest.json file when using
// gulp-rev directly. It works great if you only have one task
// but falls down when you have tasks running simultaneously as they
// overwrite each other's changes in the manifest. My approach runs
// all of the processing in parallel but generates the manifest as a
// second step in the 'build' task using the run-sequence plugin.
// Include gulp
var gulp = require('gulp');
// gulp tasks
var plumber = require('gulp-plumber');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var inject = require('gulp-inject');
var sass = require('gulp-sass');
var minifyCSS = require('gulp-minify-css');
var util = require('gulp-util');
var rev = require('gulp-rev');
var sourcemaps = require('gulp-sourcemaps');
var cached = require('gulp-cached');
var remember = require('gulp-remember');
// normal node module
var del = require('del');
var fs = require('fs');
var path = require('path');
var runSequence = require('run-sequence');
// namespace
var app = {}
// borrowed this function from gulp-inject
app.removeBasePath = function(basedir, filepath) {
return [basedir].reduce(function (path, remove) {
if (path[0] === '/' && remove[0] !== '/') {
remove = '/' + remove;
}
if (path[0] !== '/' && remove[0] === '/') {
path = '/' + path;
}
if (remove && path.indexOf(remove) === 0) {
return path.slice(remove.length);
}
return path;
}, filepath);
};
app.createManifest = function(assets, ignorePath) {
var files = fs.readdirSync(assets);
var relpath = app.removeBasePath(ignorePath, assets);
var matches = {};
for (var ii = 0; ii < files.length; ii++) {
var f = files[ii];
var ext = path.extname(f);
if (ext == '.js' || ext == '.css') {
// gulp-rev generates files like base-name-file-0123456789.ext where the hash is always 10 characters - we want everything up to that last hyphen before the hash
matches[path.basename(f, ext).slice(0, -11) + ext] = relpath + f;
}
}
// the 4 here causes it to pretty print the file for readability
fs.writeFileSync(assets + '/rev-manifest.json', JSON.stringify(matches, null, 4), 'utf-8');
};
app.addStyle = function(outputFilename, paths) {
// remove existing files matching file*.css* (get both .css and .css.map)
var glob = ['./app/assets/global/' + path.basename(outputFilename, path.extname(outputFilename)) + '*.css*'];
del(glob);
return gulp.src(paths)
.pipe(plumber())
.pipe(cached(outputFilename))
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(minifyCSS({advanced: false}))
.pipe(remember(outputFilename))
.pipe(concat(outputFilename))
.pipe(rev())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./app/assets/global/'));
};
app.addScript = function(outputFilename, paths) {
/* uglify options = {
output: { // http://lisperator.net/uglifyjs/codegen
// beautify: debug,
//comments: debug ? true : /^!|\b(copyright|license)\b|@(preserve|license|cc_on)\b/i,
semicolons: true
},
compress: { // http://lisperator.net/uglifyjs/compress, http://davidwalsh.name/compress-uglify
sequences: !debug,
booleans: !debug,
conditionals: !debug,
hoist_funs: false,
hoist_vars: debug,
warnings: debug,
},
mangle: false
}
*/
// remove existing files matching file*.css* (get both .js and .js.map)
var glob = ['./app/assets/global/' + path.basename(outputFilename, path.extname(outputFilename)) + '*.js*'];
del(glob);
return gulp.src(paths)
.pipe(cached(outputFilename))
.pipe(sourcemaps.init())
.pipe(uglify({mangle: false}).on('error', util.log))
.pipe(remember(outputFilename))
.pipe(concat(outputFilename))
.pipe(rev())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./app/assets/global/'));
};
//Lint Task
gulp.task('lint', function() {
return gulp.src('./app/assets/js/*.js')
.pipe(cached('jslint'))
.pipe(jshint())
.pipe(remember('jslint'))
.pipe(jshint.reporter('default'));
});
gulp.task('styles:core', function() {
return app.addStyle('core.css'
,['./app/assets/css/core.css'
,'./app/assets/css/core_print.css'
,'./app/assets/css/jquery.datepicker.css'
,'./app/assets/scss/core.scss']);
});
gulp.task('styles:helpscout', function() {
return app.addStyle('helpscout.css'
,['./app/assets/scss/bootstrap.scss']);
});
gulp.task('script:core', function() {
return app.addScript('core.js'
,['./app/assets/js/library/jquery/jquery.js',
,'./app/assets/js/forms/forms.js']
);
});
gulp.task('script:hotels', function() {
return app.addScript('hotels.js'
,['./app/assets/js/hotels/hotels.js'
,'./app/assets/js/hotels/hotels-services.js'
,'./app/assets/js/hotels/hotels-display.js']
);
});
gulp.task('manifest', function() {
return app.createManifest('app/assets/global/', 'app/assets');
});
// meta tasks
gulp.task('styles', ['styles:core', 'styles:helpscout']);
gulp.task('scripts', ['script:core', 'script:hotels']);
gulp.task('build', function(cb) {
runSequence(['styles', 'scripts'], 'manifest', cb);
});
// Watch Files For Changes
gulp.task('watch', function() {
gulp.watch(['./app/assets/js/*.js'
,'./app/assets/css/*.css'
,'./app/assets/css/*.scss']
,['build']);
});
// Default Task
gulp.task('default', ['lint', 'inject', 'watch']);
@ghidinelli
Copy link
Author

Rather than use the built-in gulp-rev manifest functionality, I wrote my own little function to generate the file. It's quite simple to generate from a directory full of js/css files (excluding sourcemaps). The key is to use the run-sequence plugin in the 'build' task to generate the manifest after all of the style/script tasks have run in parallel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment