Better invariant / warning replacement

This commit is contained in:
Paul O’Shannessy 2015-05-21 19:08:18 -07:00
parent 5bee4a5e29
commit 02f1626725
2 changed files with 65 additions and 13 deletions

View File

@ -67,7 +67,7 @@
}, },
"preferGlobal": true, "preferGlobal": true,
"commonerConfig": { "commonerConfig": {
"version": 6 "version": 7
}, },
"scripts": { "scripts": {
"test": "jest", "test": "jest",

76
vendor/constants.js vendored
View File

@ -37,21 +37,73 @@ module.exports = function(babel) {
CallExpression: { CallExpression: {
exit: function(node, parent) { exit: function(node, parent) {
if (this.get('callee').isIdentifier({name: 'invariant'})) { if (this.get('callee').isIdentifier({name: 'invariant'})) {
// Truncate the arguments of invariant(condition, ...) // Turns this code:
// statements to just the condition based on NODE_ENV //
// (dead code removal will remove the extra bytes). // invariant(condition, argument, argument);
return t.conditionalExpression( //
DEV_EXPRESSION, // into this:
node, //
t.callExpression(node.callee, [node.arguments[0]]) // if (!condition) {
// if ("production" !== process.env.NODE_ENV) {
// invariant(false, argument, argument);
// } else {
// invariant(false);
// }
// }
//
// Specifically this does 2 things:
// 1. Checks the condition first, preventing an extra function call.
// 2. Adds an environment check so that verbose error messages aren't
// shipped to production.
// The generated code is longer than the original code but will dead
// code removal in a minifier will strip that out.
var condition = node.arguments[0];
return t.ifStatement(
t.unaryExpression('!', condition),
t.blockStatement([
t.ifStatement(
DEV_EXPRESSION,
t.blockStatement([
t.expressionStatement(
t.callExpression(
node.callee,
[t.literal(false)].concat(node.arguments.slice(1))
)
)
]),
t.blockStatement([
t.expressionStatement(
t.callExpression(
node.callee,
[t.literal(false)]
)
)
])
)
])
); );
} else if (this.get('callee').isIdentifier({name: 'warning'})) { } else if (this.get('callee').isIdentifier({name: 'warning'})) {
// Eliminate warning(condition, ...) statements based on NODE_ENV // Turns this code:
// (dead code removal will remove the extra bytes). //
return t.conditionalExpression( // warning(condition, argument, argument);
//
// into this:
//
// if ("production" !== process.env.NODE_ENV) {
// warning(condition, argument, argument);
// }
//
// The goal is to strip out warning calls entirely in production. We
// don't need the same optimizations for conditions that we use for
// invariant because we don't care about an extra call in __DEV__
return t.ifStatement(
DEV_EXPRESSION, DEV_EXPRESSION,
node, t.blockStatement([
t.literal(null) t.expressionStatement(
node
)
])
); );
} }
} }