Last active
October 4, 2018 11:41
-
-
Save ghidinelli/e9806063ddbfa74bed7e to your computer and use it in GitHub Desktop.
Creating rev-manifest file after gulp-rev runs in parallel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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']); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.