123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /**
- * 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) {
- var t = babel.types;
- var SEEN_SYMBOL = Symbol();
- var DEV_EXPRESSION = t.binaryExpression(
- '!==',
- t.memberExpression(
- t.memberExpression(
- t.identifier('process'),
- t.identifier('env'),
- false
- ),
- t.identifier('NODE_ENV'),
- false
- ),
- t.stringLiteral('production')
- );
- return {
- visitor: {
- Identifier: {
- enter: function(path) {
- // Do nothing when testing
- if (process.env.NODE_ENV === 'test') {
- return;
- }
- // replace __DEV__ with process.env.NODE_ENV !== 'production'
- if (path.isIdentifier({name: '__DEV__'})) {
- path.replaceWith(DEV_EXPRESSION);
- }
- },
- },
- CallExpression: {
- exit: function(path) {
- var node = path.node;
- // Do nothing when testing
- if (process.env.NODE_ENV === 'test') {
- return;
- }
- // Ignore if it's already been processed
- if (node[SEEN_SYMBOL]) {
- return;
- }
- if (path.get('callee').isIdentifier({name: 'invariant'})) {
- // Turns this code:
- //
- // invariant(condition, argument, argument);
- //
- // into this:
- //
- // 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];
- var devInvariant = t.callExpression(
- node.callee,
- [t.booleanLiteral(false)].concat(node.arguments.slice(1))
- );
- devInvariant[SEEN_SYMBOL] = true;
- var prodInvariant = t.callExpression(
- node.callee,
- [t.booleanLiteral(false)]
- );
- prodInvariant[SEEN_SYMBOL] = true;
- path.replaceWith(t.ifStatement(
- t.unaryExpression('!', condition),
- t.blockStatement([
- t.ifStatement(
- DEV_EXPRESSION,
- t.blockStatement([
- t.expressionStatement(devInvariant),
- ]),
- t.blockStatement([
- t.expressionStatement(prodInvariant),
- ])
- ),
- ])
- ));
- } else if (path.get('callee').isIdentifier({name: 'warning'})) {
- // Turns this code:
- //
- // 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__
- node[SEEN_SYMBOL] = true;
- path.replaceWith(t.ifStatement(
- DEV_EXPRESSION,
- t.blockStatement([
- t.expressionStatement(
- node
- ),
- ])
- ));
- }
- },
- },
- },
- };
- };
|