mirror of https://github.com/status-im/metro.git
Make constant folding remove unused functions
Summary: Patterns like: ``` function x() { require('foo'); } const y = function() { require('bar'); } module.exports = 'potato'; ``` Are registering as dependencies `foo` and `bar`, because `x` and `y` are not stripped. This change detects both expressions and declarations, and if the binding is not referenced, the function is dropped. Reviewed By: davidaurelio Differential Revision: D8043063 fbshipit-source-id: a1deb2bcea4db6bdbe6b5ac569cbbebd0f4b1c3c
This commit is contained in:
parent
4a75826683
commit
263118c84b
|
@ -186,4 +186,65 @@ describe('constant expressions', () => {
|
|||
|
||||
expect(fold('arbitrary.js', code)).toEqual('var x=3;var y=4;var z=0;');
|
||||
});
|
||||
|
||||
it('wipes unused functions', () => {
|
||||
const code = `
|
||||
var xUnused = function () {
|
||||
console.log(100);
|
||||
};
|
||||
|
||||
var yUnused = () => {
|
||||
console.log(200);
|
||||
};
|
||||
|
||||
function zUnused() {
|
||||
console.log(300);
|
||||
}
|
||||
|
||||
var xUsed = () => {
|
||||
console.log(400);
|
||||
};
|
||||
|
||||
var yUsed = function () {
|
||||
console.log(500);
|
||||
};
|
||||
|
||||
function zUsed() {
|
||||
console.log(600);
|
||||
}
|
||||
|
||||
(() => {
|
||||
console.log(700);
|
||||
})();
|
||||
|
||||
xUsed();
|
||||
yUsed();
|
||||
zUsed();
|
||||
`;
|
||||
|
||||
expect(fold('arbitrary.js', code)).toEqual(
|
||||
[
|
||||
'var xUsed=()=>{console.log(400);};',
|
||||
'var yUsed=function(){console.log(500);};',
|
||||
'function zUsed(){console.log(600);}',
|
||||
'(()=>{console.log(700);})();',
|
||||
'xUsed();',
|
||||
'yUsed();',
|
||||
'zUsed();',
|
||||
].join(''),
|
||||
);
|
||||
});
|
||||
|
||||
it('verifies that mixes of variables and functions properly minifies', () => {
|
||||
const code = `
|
||||
var x = 2;
|
||||
var y = () => x - 2;
|
||||
|
||||
if (x) {
|
||||
z();
|
||||
}
|
||||
`;
|
||||
|
||||
expect(fold('arbitrary.js', code)).toEqual('var x=2;{z();}');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,6 +15,30 @@ import typeof {types as BabelTypes} from '@babel/core';
|
|||
function constantFoldingPlugin(context: {types: BabelTypes}) {
|
||||
const t = context.types;
|
||||
|
||||
const FunctionDeclaration = {
|
||||
exit(path: Object) {
|
||||
const binding = path.scope.getBinding(path.node.id.name);
|
||||
|
||||
if (binding && !binding.referenced) {
|
||||
path.remove();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const FunctionExpression = {
|
||||
exit(path: Object) {
|
||||
const parentPath = path.parentPath;
|
||||
|
||||
if (t.isVariableDeclarator(parentPath)) {
|
||||
const binding = parentPath.scope.getBinding(parentPath.node.id.name);
|
||||
|
||||
if (binding && !binding.referenced) {
|
||||
parentPath.remove();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const Conditional = {
|
||||
exit(path: Object) {
|
||||
const node = path.node;
|
||||
|
@ -65,12 +89,23 @@ function constantFoldingPlugin(context: {types: BabelTypes}) {
|
|||
},
|
||||
};
|
||||
|
||||
const Program = {
|
||||
exit(path: Object) {
|
||||
path.traverse({
|
||||
ArrowFunctionExpression: FunctionExpression,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
BinaryExpression: Expression,
|
||||
ConditionalExpression: Conditional,
|
||||
IfStatement: Conditional,
|
||||
LogicalExpression,
|
||||
Program,
|
||||
UnaryExpression: Expression,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue