Skip to content

Commit

Permalink
migrate to UglifyJS v3 and use its comment preservation feature inste…
Browse files Browse the repository at this point in the history
…ad of a custom regex one. this should fix a number of open issues (probably yui#19 and yui#20; not sure about yui#21)
  • Loading branch information
natevw committed Oct 17, 2017
1 parent 24200ba commit 32e2921
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 76 deletions.
75 changes: 16 additions & 59 deletions lib/jsminify.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,33 @@
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/
/*
* The comment/license workaround is based on the Ender workaround here:
* https://github.com/ender-js/Ender/blob/76961673be2a29e893d8d3dc9b97e3faf8b169a6/lib/ender.file.js#L25-58
* Ender is licensed under MIT - copyright 2012 Dustin Diaz & Jacob Thornton
* http://ender.no.de/
*/

var UglifyJS = require('uglify-js');

exports.config = {
mangle: true,
squeeze: true,
semicolon: false,
lift_vars: true,
mangle_toplevel: true,
no_mangle_functions: true,
max_line_length: 6000
output: {
semicolons: false,
max_line_len: 6000,
comments: /^!/,
},
compress: {
hoist_vars: true,
},
};

exports.jsminify = function (code, config, callback) {
if (typeof config === 'function') {
callback = config;
config = exports.config;
config = null;
}
config = config || exports.config;
var comments = [],
// trick UglifyJS.minify to preserve the token by assigning it to a variable
token = 'a="yUglify: preserved comment block"',
reMultiComments = /\/\*![\s\S]*?\*\//g,
/*
In some cases Uglify adds a comma, in others it doesn't
So we have to process the tokens twice, first with the comma
then without it to catch both cases and to be clear about it.
*/
reTokens1 = new RegExp(token + ',', 'g'),
reTokens = new RegExp(token, 'g');

try {
code = code.replace(reMultiComments, function (comment) {
comments.push(comment);
return ';' + token + ';';
});

config.ascii_only = true; // Force ascii
config.fromString = true; // Force from string

code = UglifyJS.minify(code, config).code;

//First pass with comma (comment inside code somewhere)
code = code.replace(reTokens1, function () {
return '\n' + comments.shift() + '\n';
});

//Second pass without the comma to catch normal comments
code = code.replace(reTokens, function () {
return '\n' + comments.shift() + '\n';
});

if ((code.substr(code.length - 1) === ')') ||
(code.substr(code.length - 1) === '}')) {
code += ';';
}

//Trim spaces at the beginning of the code
code = code.replace(/^\s+/, '');

code += '\n';

callback(null, code);
} catch (e) {
callback(e);

var result = UglifyJS.minify(code, config);
if (result.error) {
callback(result.error);
}
else {
callback(null, result.code);
}
};
20 changes: 4 additions & 16 deletions mocha-tests/lib/jsminify/jsminify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,9 @@ var bad = String(fs.readFileSync(path.join(__dirname, 'badSyntax.js.ignore')));

describe('JSminify Unit Tests', function () {
it('should have a default config object', function () {
var expected = {
mangle: true,
squeeze: true,
semicolon: false,
lift_vars: true,
mangle_toplevel: true,
no_mangle_functions: true,
max_line_length: 6000
};

assert.strictEqual(typeof config, 'object');

Object.keys(expected).forEach(function (key) {
assert.strictEqual(config[key], expected[key]);
});
assert.strictEqual(typeof config.output, 'object');
assert.strictEqual(typeof config.compress, 'object');
});
it('should have a jsminify function', function () {
assert.strictEqual(typeof jsminify, 'function');
Expand All @@ -35,7 +23,7 @@ describe('JSminify Unit Tests', function () {
if (err) {
return done(err);
}
assert.strictEqual(code, 'var a=function(){return!0};\n');
assert.strictEqual(code, 'var a=function(){return!0}\n');
done();
});
});
Expand All @@ -45,7 +33,7 @@ describe('JSminify Unit Tests', function () {
return done(err);
}

assert.strictEqual(code, '/*! This is a License Comment\n\t* It should persist through the uglification\n*/\n;var a=function(){return!0};\n');
assert.strictEqual(code, '/*! This is a License Comment\n\t* It should persist through the uglification\n*/\nvar a=function(){return!0}\n');
done();
});
});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "1.0.1",
"dependencies": {
"nopt": "~2.1.1",
"uglify-js": "^2.8.29",
"uglify-js": "^3.1.4",
"ycssmin": "~1.0.1"
},
"devDependencies": {
Expand Down

0 comments on commit 32e2921

Please sign in to comment.