From dcff1e52fdc7ee746caf8c5af6661d6ad12bfced Mon Sep 17 00:00:00 2001 From: Nelson Pecora Date: Fri, 21 Nov 2014 15:16:21 -0500 Subject: [PATCH 01/10] updated ncthis's PR to use grunt file api methods, added tests --- tasks/filerev.js | 12 +++++++++--- test/test.js | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index b57b795..8fc251a 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -63,13 +63,19 @@ module.exports = function (grunt) { var sourceMap = false; if (ext === '.js' || ext === '.css') { var map = file + '.map'; - resultPath += '.map'; + var resultPathMap = resultPath + '.map'; if (grunt.file.exists(map)) { if (move) { - fs.renameSync(map, resultPath); + fs.renameSync(map, resultPathMap); } else { - grunt.file.copy(map, resultPath); + grunt.file.copy(map, resultPathMap); } + + // rewrite the sourceMappingURL in files + var fileContents = grunt.file.read(resultPath, {encoding: 'utf8'}); + var newSrcMap = fileContents.replace('//# sourceMappingURL=' + path.basename(file) + '.map', '//# sourceMappingURL=' + path.basename(resultPathMap)); + + grunt.file.write(resultPath, newSrcMap, {encoding: 'utf8'}); sourceMap = true; } } diff --git a/test/test.js b/test/test.js index 1692408..ceb9893 100644 --- a/test/test.js +++ b/test/test.js @@ -45,6 +45,13 @@ it('should use same revision as .js source for the .map', function () { assert(revisioned === original); }); +it('should point the .js sourceMappingURL to the revisioned .map', function() { + var file = 'test/fixtures/math.js'; + var map = 'math.2f56179e.js.map'; + var revisioned = fs.readFileSync(hashes[file], {encoding: 'utf8'}); + assert(revisioned.indexOf('//# sourceMappingURL=' + map) !== -1); +}); + it('should revision .js file ok without any .map', function () { var file = 'test/fixtures/physics.js'; var original = fs.statSync(file).size; From cdbe0553a2010d271935707b18a148f08b7217c0 Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Fri, 21 Nov 2014 15:00:56 -1000 Subject: [PATCH 02/10] add code that updates sourceMappingURL inside of minified javascript file and also updates original file reference inside of source map file. --- tasks/filerev.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index b57b795..eb57222 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -63,13 +63,25 @@ module.exports = function (grunt) { var sourceMap = false; if (ext === '.js' || ext === '.css') { var map = file + '.map'; - resultPath += '.map'; + var resultPathMap = resultPath + '.map'; if (grunt.file.exists(map)) { if (move) { - fs.renameSync(map, resultPath); + fs.renameSync(map, resultPathMap); } else { - grunt.file.copy(map, resultPath); + grunt.file.copy(map, resultPathMap); } + + // rename sourceMappingUrl in file + var jsFileContents = grunt.file.read(resultPath, { encoding: 'utf-8' }); + var newSrcMapUrl = jsFileContents.replace(/(\/\/#\s+sourceMappingURL=)([\w\.]*.js.map)/g, '$1' + path.basename(resultPath) + '.map'); + + // update file reference inside source map file + var mapFileContents = grunt.file.readJSON(resultPathMap, { encoding: 'utf-8' }); + mapFileContents.file = path.basename(resultPath) + '.map'; + + // write files + grunt.file.write(resultPath, newSrcMapUrl, { encoding: 'utf-8' }); + grunt.file.write(resultPathMap, JSON.stringify(mapFileContents), { encoding: 'utf-8' }); sourceMap = true; } } From 6c62c1d007dbf53c13eb9b78ea024fe2109ea3a4 Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Fri, 21 Nov 2014 16:27:22 -1000 Subject: [PATCH 03/10] add test to check if sourceMappingURL points to new file rev'd source map file --- test/test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test.js b/test/test.js index 1692408..4a4b57f 100644 --- a/test/test.js +++ b/test/test.js @@ -45,6 +45,13 @@ it('should use same revision as .js source for the .map', function () { assert(revisioned === original); }); +it('should point the .js sourceMappingURL to the revisioned .map', function() { + var file = 'test/fixtures/math.js'; + var map = path.basename(hashes[file] + '.map'); + var revisioned = fs.readFileSync(hashes[file], {encoding: 'utf8'}); + assert(revisioned.indexOf('//# sourceMappingURL=' + map) !== -1); +}); + it('should revision .js file ok without any .map', function () { var file = 'test/fixtures/physics.js'; var original = fs.statSync(file).size; From 40e32ebfba2414ade63fe4ebe818fdccfd5b4ce9 Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Fri, 21 Nov 2014 16:28:30 -1000 Subject: [PATCH 04/10] update test to check that rev number matches between .js and .map files --- test/test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 4a4b57f..74db664 100644 --- a/test/test.js +++ b/test/test.js @@ -1,5 +1,6 @@ 'use strict'; var fs = require('fs'); +var path = require('path'); var assert = require('assert'); var hashes = { @@ -40,8 +41,8 @@ it('should allow sources defined with expand', function () { it('should use same revision as .js source for the .map', function () { var file = 'test/fixtures/math.js.map'; - var original = fs.statSync(file).size; - var revisioned = fs.statSync(hashes[file]).size; + var original = path.basename(hashes[file]); + var revisioned = path.basename(hashes[file] + '.map', '.map'); assert(revisioned === original); }); From a875cd26807c82dcee5a0d590949e42eda28811f Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Mon, 24 Nov 2014 13:32:16 -1000 Subject: [PATCH 05/10] update test with proper assertion library method --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 0450a20..375b2f1 100644 --- a/test/test.js +++ b/test/test.js @@ -50,7 +50,7 @@ it('should point the .js sourceMappingURL to the revisioned .map', function() { var file = 'test/fixtures/math.js'; var map = 'math.2f56179e.js.map'; var revisioned = fs.readFileSync(hashes[file], {encoding: 'utf8'}); - assert(revisioned.indexOf('//# sourceMappingURL=' + map) !== -1); + assert.notStrictEqual(revisioned.indexOf('//# sourceMappingURL=' + map), -1); }); it('should revision .js file ok without any .map', function () { From cc7af46b2afb6f0a0ce12eeaaab5499af32e87b2 Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Mon, 24 Nov 2014 13:41:57 -1000 Subject: [PATCH 06/10] fix(filerev.js): remove passing argument to grunt.file methods that have it as a default value --- tasks/filerev.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index 159e1fd..74879af 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -72,15 +72,15 @@ module.exports = function (grunt) { } // rewrite the sourceMappingURL in files - var fileContents = grunt.file.read(resultPath, {encoding: 'utf8'}); + var fileContents = grunt.file.read(resultPath); var newSrcMap = fileContents.replace('//# sourceMappingURL=' + path.basename(file) + '.map', '//# sourceMappingURL=' + path.basename(resultPathMap)); // update file reference inside source map file - var mapFileContents = grunt.file.readJSON(resultPathMap, { encoding: 'utf-8' }); + var mapFileContents = grunt.file.readJSON(resultPathMap); mapFileContents.file = path.basename(resultPath) + '.map'; // write files - grunt.file.write(resultPath, newSrcMap, {encoding: 'utf8'}); - grunt.file.write(resultPathMap, JSON.stringify(mapFileContents), { encoding: 'utf-8' }); + grunt.file.write(resultPath, newSrcMap); + grunt.file.write(resultPathMap, JSON.stringify(mapFileContents)); sourceMap = true; } } From df0768717543437c406d149f35fc8d63bfc56e2f Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Wed, 26 Nov 2014 15:29:45 -1000 Subject: [PATCH 07/10] add regex for finding sourceMappingURL in file that supports absolute and relative paths --- tasks/filerev.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index 74879af..a05340f 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -64,23 +64,38 @@ module.exports = function (grunt) { if (ext === '.js' || ext === '.css') { var map = file + '.map'; var resultPathMap = resultPath + '.map'; + if (grunt.file.exists(map)) { + var fileContents = grunt.file.read(resultPath); + var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.]+\b\w+[\.js|\.css]\.map)/gi; + var regexResult = srcMapRegex.exec(fileContents); + var srcRelativePath = path.dirname(resultPath) + '/' + regexResult[2] + regexResult[3]; + if (move) { - fs.renameSync(map, resultPathMap); + try { + fs.renameSync(map, resultPathMap); + } catch (err) { + // if map is not in the same directory, must be relative path + grunt.verbose.writeln('Source Map not found in: ' + map); + grunt.verbose.writeln('Trying Relative Path: : ' + srcRelativePath); + resultPathMap = srcRelativePath; + fs.renameSync(srcRelativePath, srcRelativePath); + } } else { grunt.file.copy(map, resultPathMap); } // rewrite the sourceMappingURL in files - var fileContents = grunt.file.read(resultPath); - var newSrcMap = fileContents.replace('//# sourceMappingURL=' + path.basename(file) + '.map', '//# sourceMappingURL=' + path.basename(resultPathMap)); + var newSrcMapUrl = fileContents.replace(srcMapRegex, '$1' + ('$2' || '') + path.basename(resultPath) + '.map'); // update file reference inside source map file - var mapFileContents = grunt.file.readJSON(resultPathMap); - mapFileContents.file = path.basename(resultPath) + '.map'; + var srcFileReference = grunt.file.readJSON(resultPathMap); + srcFileReference.file = path.basename(resultPath); - // write files - grunt.file.write(resultPath, newSrcMap); - grunt.file.write(resultPathMap, JSON.stringify(mapFileContents)); + if (grunt.file.exists(srcRelativePath)) { + grunt.file.delete(srcRelativePath); + } + grunt.file.write(resultPath, newSrcMapUrl); + grunt.file.write(path.dirname(srcRelativePath) + '/' + path.basename(resultPath) + '.map', JSON.stringify(srcFileReference)); sourceMap = true; } } From 1e029d9467c86768a3e54423617449baad332bec Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Wed, 26 Nov 2014 15:40:40 -1000 Subject: [PATCH 08/10] normalize indentation to 2 spaces --- tasks/filerev.js | 74 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index a05340f..df3c64f 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -62,49 +62,49 @@ module.exports = function (grunt) { // Source maps var sourceMap = false; if (ext === '.js' || ext === '.css') { - var map = file + '.map'; - var resultPathMap = resultPath + '.map'; - - if (grunt.file.exists(map)) { - var fileContents = grunt.file.read(resultPath); - var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.]+\b\w+[\.js|\.css]\.map)/gi; - var regexResult = srcMapRegex.exec(fileContents); - var srcRelativePath = path.dirname(resultPath) + '/' + regexResult[2] + regexResult[3]; - - if (move) { - try { - fs.renameSync(map, resultPathMap); - } catch (err) { - // if map is not in the same directory, must be relative path - grunt.verbose.writeln('Source Map not found in: ' + map); - grunt.verbose.writeln('Trying Relative Path: : ' + srcRelativePath); - resultPathMap = srcRelativePath; - fs.renameSync(srcRelativePath, srcRelativePath); - } - } else { - grunt.file.copy(map, resultPathMap); + var map = file + '.map'; + var resultPathMap = resultPath + '.map'; + + if (grunt.file.exists(map)) { + var fileContents = grunt.file.read(resultPath); + var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.]+\b\w+[\.js|\.css]\.map)/gi; + var regexResult = srcMapRegex.exec(fileContents); + var srcRelativePath = path.dirname(resultPath) + '/' + regexResult[2] + regexResult[3]; + + if (move) { + try { + fs.renameSync(map, resultPathMap); + } catch (err) { + // if map is not in the same directory, must be relative path + grunt.verbose.writeln('Source Map not found in: ' + map); + grunt.verbose.writeln('Trying Relative Path: : ' + srcRelativePath); + resultPathMap = srcRelativePath; + fs.renameSync(srcRelativePath, srcRelativePath); } - - // rewrite the sourceMappingURL in files - var newSrcMapUrl = fileContents.replace(srcMapRegex, '$1' + ('$2' || '') + path.basename(resultPath) + '.map'); - // update file reference inside source map file - var srcFileReference = grunt.file.readJSON(resultPathMap); - srcFileReference.file = path.basename(resultPath); - - if (grunt.file.exists(srcRelativePath)) { - grunt.file.delete(srcRelativePath); - } - grunt.file.write(resultPath, newSrcMapUrl); - grunt.file.write(path.dirname(srcRelativePath) + '/' + path.basename(resultPath) + '.map', JSON.stringify(srcFileReference)); - sourceMap = true; - } + } else { + grunt.file.copy(map, resultPathMap); + } + + // rewrite the sourceMappingURL in files + var newSrcMapUrl = fileContents.replace(srcMapRegex, '$1' + ('$2' || '') + path.basename(resultPath) + '.map'); + // update file reference inside source map file + var srcFileReference = grunt.file.readJSON(resultPathMap); + srcFileReference.file = path.basename(resultPath); + + if (grunt.file.exists(srcRelativePath)) { + grunt.file.delete(srcRelativePath); + } + grunt.file.write(resultPath, newSrcMapUrl); + grunt.file.write(path.dirname(srcRelativePath) + '/' + path.basename(resultPath) + '.map', JSON.stringify(srcFileReference)); + sourceMap = true; + } } filerev.summary[path.normalize(file)] = path.join(dirname, newName); grunt.verbose.writeln(chalk.green('✔ ') + file + chalk.gray(' changed to ') + newName); if (sourceMap) { - filerev.summary[path.normalize(file + '.map')] = path.join(dirname, newName + '.map'); - grunt.verbose.writeln(chalk.green('✔ ') + file + '.map' + chalk.gray(' changed to ') + newName + '.map'); + filerev.summary[path.normalize(file + '.map')] = path.join(dirname, newName + '.map'); + grunt.verbose.writeln(chalk.green('✔ ') + file + '.map' + chalk.gray(' changed to ') + newName + '.map'); } }); From 325c50dd2acc2112660b46d27f9d9fd9db3b5892 Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Wed, 26 Nov 2014 16:06:01 -1000 Subject: [PATCH 09/10] fix(regex): regex would ignore non-releative paths to sourcemap files if name included the "-" character --- tasks/filerev.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index df3c64f..8ce8263 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -67,7 +67,7 @@ module.exports = function (grunt) { if (grunt.file.exists(map)) { var fileContents = grunt.file.read(resultPath); - var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.]+\b\w+[\.js|\.css]\.map)/gi; + var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.\-]+\b\w+[\.js|\.css]\.map)/gi; var regexResult = srcMapRegex.exec(fileContents); var srcRelativePath = path.dirname(resultPath) + '/' + regexResult[2] + regexResult[3]; From ff1bccb47b5858326dc7cdd64ee00b3c27374755 Mon Sep 17 00:00:00 2001 From: Ray Farias Date: Wed, 26 Nov 2014 21:13:53 -1000 Subject: [PATCH 10/10] fix sourcemap not rev'ing if not in the same directory as parent file --- tasks/filerev.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/tasks/filerev.js b/tasks/filerev.js index 8ce8263..eed8c4f 100644 --- a/tasks/filerev.js +++ b/tasks/filerev.js @@ -64,23 +64,31 @@ module.exports = function (grunt) { if (ext === '.js' || ext === '.css') { var map = file + '.map'; var resultPathMap = resultPath + '.map'; + var fileContents = grunt.file.read(resultPath); + var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.\-]+\b\w+[\.js|\.css]\.map)/gi; + var regexResult; + var srcRelativePath; + var srcRelativePathExists; + + try { + regexResult = srcMapRegex.exec(fileContents); + srcRelativePath = path.dirname(resultPath) + '/' + regexResult[2] + regexResult[3]; + srcRelativePathExists = true; + } catch (err) { + srcRelativePathExists = false; + } - if (grunt.file.exists(map)) { - var fileContents = grunt.file.read(resultPath); - var srcMapRegex = /(sourceMappingURL\=)([\w\-\/\.]+(?![\b\w\.]+[\.js|\.css]\.map)\/)?([\w\.\-]+\b\w+[\.js|\.css]\.map)/gi; - var regexResult = srcMapRegex.exec(fileContents); - var srcRelativePath = path.dirname(resultPath) + '/' + regexResult[2] + regexResult[3]; - + if (grunt.file.exists(map) || srcRelativePathExists) { if (move) { - try { - fs.renameSync(map, resultPathMap); - } catch (err) { - // if map is not in the same directory, must be relative path - grunt.verbose.writeln('Source Map not found in: ' + map); - grunt.verbose.writeln('Trying Relative Path: : ' + srcRelativePath); - resultPathMap = srcRelativePath; - fs.renameSync(srcRelativePath, srcRelativePath); - } + try { + fs.renameSync(map, resultPathMap); + } catch (err) { + // if map is not in the same directory, must be relative path + grunt.verbose.writeln('Source Map not found in: ' + map); + grunt.verbose.writeln('Trying Relative Path: : ' + srcRelativePath); + resultPathMap = srcRelativePath; + fs.renameSync(srcRelativePath, srcRelativePath); + } } else { grunt.file.copy(map, resultPathMap); }