From 607abf89f7d4e6979a8c9eae6dbb9814bc604655 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 21 Jan 2013 01:13:51 -0800 Subject: [PATCH] Move generic Closure Compiler fixes into build/minify.js. Former-commit-id: 8492f60a67cbf7a2d7d3118f9653e6997ab1d15b --- build.js | 16 ---------- build/minify.js | 64 ++++++++++++++++++++++++++++++---------- build/post-compile.js | 12 ++------ lodash.min.js | 2 +- lodash.underscore.js | 2 +- lodash.underscore.min.js | 2 +- 6 files changed, 54 insertions(+), 44 deletions(-) diff --git a/build.js b/build.js index 3692660a6..a3613933d 100755 --- a/build.js +++ b/build.js @@ -2174,12 +2174,6 @@ if (!isDebug) { outputPath || (outputPath = path.join(cwd, basename + '.min.js')); - // convert the IIFE into a function call so Closure Compiler (advanced) won't strip it - if (!isIIFE) { - source = source - .replace(/\(function/, 'iife$&') - .replace(/\(this\)\)(;\s*)$/, ', this)$1'); - } minify(source, { 'filePath': filePath, 'isMapped': isMapped, @@ -2188,16 +2182,6 @@ 'modes': isIIFE && ['simple', 'hybrid'], 'outputPath': outputPath, 'onComplete': function(data) { - // restore IIFE - if (!isIIFE) { - data.source = data.source - .replace(/iife\(/, '(') - .replace(/, *this\)([\s;]*(\n\/\/.+)?)$/, '(this))$1'); - } - // inject "use strict" directive - if (isStrict) { - data.source = data.source.replace(/^([\s\S]*?function[^{]+{\s*)([^"'])/, '$1"use strict";$2'); - } if (isCustom) { data.source = addCommandsToHeader(data.source, options); } diff --git a/build/minify.js b/build/minify.js index ceca16238..6e1bacb4f 100755 --- a/build/minify.js +++ b/build/minify.js @@ -303,32 +303,46 @@ */ function closureCompile(source, mode, callback) { var filePath = this.filePath, - outputPath = this.outputPath, + isAdvanced = mode == 'advanced', isMapped = this.isMapped, mapPath = getMapPath(outputPath), - options = closureOptions.slice(); + options = closureOptions.slice(), + outputPath = this.outputPath; + + // remove copyright header to make other modifications easier + var license = (/^(?:\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*/.exec(source) || [''])[0]; + if (license) { + source = source.replace(license, ''); + } + + var hasIIFE = /^;?\(function[^{]+{\s*/.test(source), + isStrict = hasIIFE && /^;?\(function[^{]+{\s*["']use strict["']/.test(source); + + // to avoid stripping the IIFE, convert it to a function call + if (hasIIFE && isAdvanced) { + source = source + .replace(/\(function/, '__iife__$&') + .replace(/\(this\)\)([\s;]*(\n\/\/.+)?)$/, ', this)$1'); + } options.push('--compilation_level=' + optimizationModes[mode]); - if (isMapped) { options.push('--create_source_map=' + mapPath, '--source_map_format=V3'); } - // the standard error stream, standard output stream, and the Closure Compiler process - var error = '', - output = '', - compiler = spawn('java', ['-jar', closurePath].concat(options)); + var compiler = spawn('java', ['-jar', closurePath].concat(options)); if (!this.isSilent) { console.log('Compressing ' + path.basename(outputPath, '.js') + ' using the Closure Compiler (' + mode + ')...'); } - compiler.stdout.on('data', function(data) { - // append the data to the output stream - output += data; + + var error = ''; + compiler.stderr.on('data', function(data) { + error += data; }); - compiler.stderr.on('data', function(data) { - // append the error message to the error stream - error += data; + var output = ''; + compiler.stdout.on('data', function(data) { + output += data; }); compiler.on('exit', function(status) { @@ -337,6 +351,21 @@ var exception = new Error(error); exception.status = status; } + // restore IIFE and move exposed vars inside the IIFE + if (hasIIFE && isAdvanced) { + output = output + .replace(/__iife__\(/, '(') + .replace(/,\s*this\)([\s;]*(\n\/\/.+)?)$/, '(this))$1') + .replace(/^((?:var (?:\w+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^{]+{)/, '$2$1'); + } + // inject "use strict" directive + if (isStrict) { + output = output.replace(/^[\s\S]*?function[^{]+{/, '$&"use strict";'); + } + // restore copyright header + if (license) { + output = license + output; + } if (isMapped) { var mapOutput = fs.readFileSync(mapPath, 'utf8'); fs.unlinkSync(mapPath); @@ -534,8 +563,13 @@ this.uglified.gzip = result; } // minify the already Closure Compiler simple optimized source using UglifyJS - if (this.modes.indexOf('hybrid') > -1) { - uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this)); + var modes = this.modes; + if (modes.indexOf('hybrid') > -1) { + if (modes.indexOf('simple') > -1) { + uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this)); + } else if (modes.indexOf('advanced') > -1) { + onSimpleHybridGzip.call(this); + } } else { onComplete.call(this); } diff --git a/build/post-compile.js b/build/post-compile.js index 2dcdccdf5..8091d1d08 100644 --- a/build/post-compile.js +++ b/build/post-compile.js @@ -24,22 +24,14 @@ * @returns {String} Returns the processed source. */ function postprocess(source) { - // remove old copyright/license header + // remove copyright header source = source.replace(/^\/\**[\s\S]+?\*\/\n/, ''); - // move vars exposed by the Closure Compiler into the IIFE - source = source.replace(/^((?:var (?:\w+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^)]+\){)/, '$2$1'); - // correct overly aggressive Closure Compiler advanced optimizations source = source .replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}') .replace(/(document[^&]+&&)\s*\w+/, '$1!({toString:0}+"")'); - // unescape properties (e.g. foo["bar"] => foo.bar) - source = source.replace(/(\w)\["([^."]+)"\]/g, function(match, left, right) { - return /\W/.test(right) ? match : (left + '.' + right); - }); - // flip `typeof` expressions to help optimize Safari and // correct the AMD module definition for AMD build optimizers // (e.g. from `"number" == typeof x` to `typeof x == "number") @@ -56,7 +48,7 @@ if (!snippet) { return source; } - // add new copyright/license header + // add new copyright header var version = snippet[2]; source = licenseTemplate.replace('<%= VERSION %>', version) + '\n;' + source; diff --git a/lodash.min.js b/lodash.min.js index 38ca3c18b..9f4f9f4c2 100644 --- a/lodash.min.js +++ b/lodash.min.js @@ -38,4 +38,4 @@ return e=arguments,o=this,0