Skip to content

Commit

Permalink
Deploy: custom compression options for handling edge cases.
Browse files Browse the repository at this point in the history
Allows overriding every option for:

- compression
- mangle
- special *

* Special is a set of additional options specifically for exceptional cases
  • Loading branch information
rwaldron committed Mar 10, 2016
1 parent 30a8fed commit c114a0b
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 27 deletions.
27 changes: 26 additions & 1 deletion lib/tessel/deploy-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,30 @@ module.exports = {
'negotiator/**/*.js',
'socket.io-client/socket.io.js',
'mime/types/*.types'
]
],
compressionOptions: {
'extend': {
special: {
/*
The "extend" module uses the following unadvisable pattern:
module.exports = function NAME() {
... later calls NAME()
};
UglifyJS's compression algorithm wants to remove that unnecessary
function expression _name_. That's ok, because we can just as
easily use `keep_fnames: true` to avoid that removal. Unfortunately,
that's not enough in this case, as mangling produces sometimes
requires another pass with `figure_out_scope` to avoid
unhygienic mangling.
*/
rescope_after_mangle: true
},
compress: {
keep_fnames: true
},
mangle: {}
},
},
};
69 changes: 44 additions & 25 deletions lib/tessel/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,14 +785,15 @@ actions.tarBundle = function(opts) {
var isJS = dependency.file.endsWith('.js');
var source = dependency.source;
var target = path.normalize(dependency.file.replace(absRoot, tempBundleDir));
var compressionOptions = deployLists.compressionOptions[dependency.packageName];

if (opts.single && !dependency.entry) {
return;
}

if (isJS) {
try {
source = actions.compress(source);
source = actions.compress(source, compressionOptions);
} catch (error) {
reject(error);
}
Expand Down Expand Up @@ -996,14 +997,49 @@ actions.project = function(options) {
return new Project(options);
};

actions.compress = function(source) {
actions.compress = function(source, options) {
source = typeof source === 'string' ? source : source.toString();

options = options || {
compress: {},
mangle: {},
special: {},
};

var compress = {
// ------
booleans: true,
cascade: true,
conditionals: true,
comparisons: true,
evaluate: true,
hoist_funs: true,
hoist_vars: true,
if_return: true,
join_vars: true,
loops: true,
properties: true,
screw_ie8: true,
sequences: true,
unsafe: true,
// ------
keep_fargs: false,
keep_fnames: false,
warnings: false,
drop_console: false,
};
var mangle = {
sort: true,
toplevel: true
toplevel: true,
};
var special = {
rescope_after_mangle: false,
};

Object.assign(compress, options.compress || {});
Object.assign(mangle, options.mangle || {});
Object.assign(special, options.special || {});

var ast;

try {
Expand Down Expand Up @@ -1044,33 +1080,16 @@ actions.compress = function(source) {
// really shouldn't be our problem, but it happens.
try {
ast.figure_out_scope();
ast = ast.transform(uglify.Compressor({
// ------
booleans: true,
cascade: true,
conditionals: true,
comparisons: true,
evaluate: true,
hoist_funs: true,
hoist_vars: true,
if_return: true,
join_vars: true,
loops: true,
properties: true,
screw_ie8: true,
sequences: true,
unsafe: true,
// ------
keep_fargs: false,
keep_fnames: false,
warnings: false,
drop_console: false,
}));
ast = ast.transform(uglify.Compressor(compress));

ast.figure_out_scope(mangle);
ast.compute_char_frequency(mangle);
ast.mangle_names(mangle);

if (special.rescope_after_mangle) {
ast.figure_out_scope(mangle);
}

var stream = uglify.OutputStream();

ast.print(stream);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"ssh2": "^0.4.2",
"sshpk": "^1.6.0",
"stream-to-buffer": "^0.1.0",
"t2-project": "^0.0.6",
"t2-project": "^0.1.0",
"tar": "^2.1.1",
"tar-stream": "^1.3.0",
"uglify-js": "^2.5.0",
Expand Down
26 changes: 26 additions & 0 deletions test/unit/deploy-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,31 @@ exports['deploy-lists'] = {

test.deepEqual(deployLists.includes, includes);
test.done();
},

checkCompression: function(test) {
test.expect(1);

/*
This test just ensures that no one accidentally
messes up the contents of the deploy-lists file,
specifically for the compression options field
*/
var compressionOptions = {
extend: {
special: {
rescope_after_mangle: true
},
compress: {
keep_fnames: true
},
mangle: {}
},
};

test.deepEqual(deployLists.compressionOptions, compressionOptions);
test.done();
}

};
40 changes: 40 additions & 0 deletions test/unit/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,46 @@ exports['deploy.compress'] = {
test.done();
},

theirCompressorOptions: function(test) {
test.expect(18);

var theirExplicitSettings = {
// ------
booleans: false,
cascade: false,
conditionals: false,
comparisons: false,
evaluate: false,
hoist_funs: false,
hoist_vars: false,
if_return: false,
join_vars: false,
loops: false,
properties: false,
screw_ie8: false,
sequences: false,
unsafe: false,
// ------
keep_fargs: true,
keep_fnames: true,
warnings: true,
drop_console: true,
};

var theirExplicitSettingsKeys = Object.keys(theirExplicitSettings);

deploy.compress('var a = 1;', {
compress: theirExplicitSettings
});

var optionsSeen = this.Compressor.lastCall.args[0];

theirExplicitSettingsKeys.forEach(key => {
test.equal(optionsSeen[key], theirExplicitSettings[key]);
});

test.done();
},
minifyFromBuffer: function(test) {
test.expect(1);
test.equal(deploy.compress(new Buffer(codeContents)), codeContents);
Expand Down

0 comments on commit c114a0b

Please sign in to comment.