mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Add a build step to hoist warning conditions (#12537)
This commit is contained in:
49
scripts/babel/__tests__/wrap-warning-with-env-check-test.js
Normal file
49
scripts/babel/__tests__/wrap-warning-with-env-check-test.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/* eslint-disable quotes */
|
||||
'use strict';
|
||||
|
||||
let babel = require('babel-core');
|
||||
let wrapWarningWithEnvCheck = require('../wrap-warning-with-env-check');
|
||||
|
||||
function transform(input) {
|
||||
return babel.transform(input, {
|
||||
plugins: [wrapWarningWithEnvCheck],
|
||||
}).code;
|
||||
}
|
||||
|
||||
function compare(input, output) {
|
||||
const compiled = transform(input);
|
||||
expect(compiled).toEqual(output);
|
||||
}
|
||||
|
||||
let oldEnv;
|
||||
|
||||
describe('wrap-warning-with-env-check', () => {
|
||||
beforeEach(() => {
|
||||
oldEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = '';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env.NODE_ENV = oldEnv;
|
||||
});
|
||||
|
||||
it('should wrap warning calls', () => {
|
||||
compare(
|
||||
"warning(condition, 'a %s b', 'c');",
|
||||
"__DEV__ ? !condition ? warning(false, 'a %s b', 'c') : void 0 : void 0;"
|
||||
);
|
||||
});
|
||||
|
||||
it('should not wrap invariant calls', () => {
|
||||
compare(
|
||||
"invariant(condition, 'a %s b', 'c');",
|
||||
"invariant(condition, 'a %s b', 'c');"
|
||||
);
|
||||
});
|
||||
});
|
||||
64
scripts/babel/wrap-warning-with-env-check.js
Normal file
64
scripts/babel/wrap-warning-with-env-check.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = function(babel, options) {
|
||||
const t = babel.types;
|
||||
|
||||
const DEV_EXPRESSION = t.identifier('__DEV__');
|
||||
|
||||
const SEEN_SYMBOL = Symbol('expression.seen');
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression: {
|
||||
exit: function(path) {
|
||||
const node = path.node;
|
||||
|
||||
// Ignore if it's already been processed
|
||||
if (node[SEEN_SYMBOL]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (path.get('callee').isIdentifier({name: 'warning'})) {
|
||||
// Turns this code:
|
||||
//
|
||||
// warning(condition, argument, argument);
|
||||
//
|
||||
// into this:
|
||||
//
|
||||
// if (__DEV__) {
|
||||
// if (!condition) {
|
||||
// warning(false, argument, argument);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// The goal is to strip out warning calls entirely in production
|
||||
// and to avoid evaluating the arguments in development.
|
||||
const condition = node.arguments[0];
|
||||
const newNode = t.callExpression(
|
||||
node.callee,
|
||||
[t.booleanLiteral(false)].concat(node.arguments.slice(1))
|
||||
);
|
||||
newNode[SEEN_SYMBOL] = true;
|
||||
path.replaceWith(
|
||||
t.ifStatement(
|
||||
DEV_EXPRESSION,
|
||||
t.blockStatement([
|
||||
t.ifStatement(
|
||||
t.unaryExpression('!', condition),
|
||||
t.expressionStatement(newNode)
|
||||
),
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user