From 908071afbf32c46fe9110e4a67e104bbd4b3a56b Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Fri, 7 Jun 2013 10:25:07 -0700 Subject: [PATCH] feat(Grunt): add source maps to all min files Generate source map files when build step is ran and adds source map headers to all min files. Source map url must be appended to the min file otherwise the line offsets will be off. Inspired by Ryan Seddon (PR #2858) Closes #1714 --- lib/grunt/utils.js | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/grunt/utils.js b/lib/grunt/utils.js index 27765b76a5bf..3d2ab316e586 100644 --- a/lib/grunt/utils.js +++ b/lib/grunt/utils.js @@ -112,27 +112,44 @@ module.exports = { }, - singleStrict: function(src, insert, newline){ - var useStrict = newline ? "$1\n'use strict';" : "$1'use strict';"; + singleStrict: function(src, insert){ return src .replace(/\s*("|')use strict("|');\s*/g, insert) // remove all file-specific strict mode flags - .replace(/(\(function\([^)]*\)\s*\{)/, useStrict); // add single strict mode flag + .replace(/(\(function\([^)]*\)\s*\{)/, "$1'use strict';"); // add single strict mode flag + }, + + + sourceMap: function(mapFile, fileContents) { + // use the following once Chrome beta or stable supports the //# pragma + // var sourceMapLine = '//# sourceMappingURL=' + mapFile + '\n'; + var sourceMapLine = '/*\n//@ sourceMappingURL=' + mapFile + '\n*/\n'; + return fileContents + sourceMapLine; }, min: function(file, done) { var minFile = file.replace(/\.js$/, '.min.js'); + var mapFile = minFile + '.map'; + var mapFileName = mapFile.match(/[^\/]+$/)[0]; shell.exec( 'java ' + this.java32flags() + ' ' + '-jar components/closure-compiler/compiler.jar ' + '--compilation_level SIMPLE_OPTIMIZATIONS ' + '--language_in ECMASCRIPT5_STRICT ' + + '--source_map_format=V3 ' + + '--create_source_map ' + mapFile + ' ' + '--js ' + file + ' ' + '--js_output_file ' + minFile, function(code) { if (code !== 0) grunt.fail.warn('Error minifying ' + file); - grunt.file.write(minFile, this.singleStrict(grunt.file.read(minFile), '\n')); + + // closure creates the source map relative to build/ folder, we need to strip those references + grunt.file.write(mapFile, grunt.file.read(mapFile).replace('"file":"build/', '"file":"'). + replace('"sources":["build/','"sources":["')); + + // move add use strict into the closure + add source map pragma + grunt.file.write(minFile, this.sourceMap(mapFileName, this.singleStrict(grunt.file.read(minFile), '\n'))); grunt.log.ok(file + ' minified into ' + minFile); done(); }.bind(this));