Last active
May 24, 2016 08:44
-
-
Save CodeXT1/890d0e990d5e2bd1e8fe to your computer and use it in GitHub Desktop.
RequireJS, r.js multi-bundle edge case with Gulp-Rev-All. RequireJS doesn't like to have .js extentions on bundles, even though they often map directly to .js files, so Gulp-Rev-All misses them. This is a very hack script I made to run after Gulp-Rev-All has hashed everything else. It loads *.js files in the final build directory and parses out …
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
var gulp = require('gulp'), | |
glob = require('glob'), | |
$ = require('gulp-load-plugins'); | |
//Needs gulp-replace too, you'll see | |
//and gulp-rev-all is assumed to have already been run on the whole build dir. | |
// This is the gulp task to replace the few missed link references in the RequireJS | |
// common bundle after using the Gulp-Rev-All to hash and update everything else | |
gulp.task('bundle-replace', function() { | |
// Select the RequireJS main scripts*.js bundle as it will be our final output | |
// and it is a good start for of the gulp pipe. It has gone through | |
// "r.js optimzer" and Gulp-Rev-All already, hence the *.js to grab it with the | |
// hash | |
return gulp.src(['./build/scripts*.js']) | |
// Use Gulp-replace aliased to $.replace. We are using RegEx to target the lazy | |
// loaded bundles inside the scripts*.js, they will have patterns like | |
// "about":[ or "chart":[ or "options-page":[ etc, that map to real .js files | |
// if they had .js extensions added to them. The variable "p1" holds onto the | |
// Regex Capture Group () that found the base filenames of the bundles we want | |
// to change and we will match against it later. | |
// (RequireJS doesn't like .js extensions on the bundles, but I tested it | |
// anyway and if they could have .js added then Rev-All finds them, | |
// so great work, had they been normal file links this wouldn't be an issue | |
// but RequireJS wants to not have .js added on the end) | |
// http://imgur.com/n5dbBTO.png This is an image example of the bundles that need to | |
// be hashed, and these are what this first RegEx finds for us in our common bundle | |
.pipe($.replace(/\"([^"]*)\"\:\s?\[\s*\"/g, function(match, p1) { | |
// Glob assign all *.js files in Build Dir that have already be rev'd with Rev-All | |
var allRevFiles = glob.sync('./build/*.js'); | |
// Turn the JSON glob into a jsonString | |
var jsonString = JSON.stringify(allRevFiles); | |
// this RegEx has two Capture groups with () inside () if you notice: | |
// one with the full file name and hash, without the .js, what we want it to turn into | |
// and one with just the file name, no hash and no .js, what it currently is, and what | |
// is currently being stored in the "p1" variable to be matched against later | |
var regEx = /\"\.\/[a-z]*\/(([^\"\/.]*).[a-z0-9.]*)\.js\"/ig | |
// Define a single plainFile to loop with, and a allPlainFiles array to push results into | |
var plainFile; | |
var allPlainFiles = []; | |
// loop through the matching RegEx compared to all our hashed *.js files in Build Dir | |
// to build our array | |
while (plainFile = regEx.exec(jsonString)){ | |
// Push Capture group 1 and 2 into the array | |
allPlainFiles.push(plainFile[2]); | |
allPlainFiles.push(plainFile[1]); | |
}; | |
// simple loop over the size of the allPlainFiles Array | |
for (var i = 0; i < allPlainFiles.length; i++) { | |
// if the Capture group 2 matches the "p1" found in the file, replace it with Capture | |
// group 1's related full filename, the one with the hash added so +1 in | |
// the Array compared to the one the matched so we replace it with what we want. | |
if (allPlainFiles[i] === p1) { | |
// return it with extra formatting because the first RegEx we did removes some extra | |
// characters with its matching due to having to match against extra symbols like ":[ | |
// in order to make sure the bundle names it found were unique in the fully concatenated | |
// common bundle scripts*.js file, because there are other libraries in there too now. | |
// So Add back in a starting " and a closing ":[ | |
return "\""+ allPlainFiles[i+1] +"\"\:\[\""; | |
} | |
}; | |
})) | |
// This is final pipe writes the changes to Scripts*.js with gulp-replace to change the | |
// desired bundle names to the hashed versions. It all takes about 40ms to finish, great hack. | |
.pipe(gulp.dest('./build')); | |
}); | |
// This image is how it should look after being replaced, and works it works now that the | |
// Bundle Names are hashed! http://imgur.com/xlPGbBT.png | |
// The RegEx is used was built and tested with http://www.regexr.com/, great site. | |
// This is a small example of a jsonString from the Gist that would represent the .js files | |
// in your build dir after using Rev-All, and you'd match it with | |
//from line 42 | |
// /\"\.\/[a-z]*\/(([^\"\/.]*).[a-z0-9.]*)\.js\"/ig | |
// ["./build/about.4633414d.js","./build/back-end.4633414d.js","./build/charts.fb997bcb.js", | |
// "./build/etc.fb997bcb.js","./build/scripts.ee82b2ec.js"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment