mirror of
https://github.com/facebook/react.git
synced 2026-02-24 04:33:04 +00:00
The error transform works by replacing calls to `invariant` with an `if` statement. Since we're replacing a call expression with a statement, Babel wraps the new statement in an immediately-invoked function expression (IIFE). This wrapper is unnecessary in practice because our `invariant` calls are always part of their own expression statement. In the production bundle, the function wrappers are removed by Closure. But they remain in the development bundles. This commit updates the transform to confirm that an `invariant` call expression's parent node is an expression statement. (If not, it throws a transform error.) Then, it replaces the expression statement instead of the expression itself, effectively removing the extraneous IIFE wrapper.
97 lines
2.4 KiB
JavaScript
97 lines
2.4 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* 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 devExpressionWithCodes = require('../transform-error-messages');
|
|
|
|
function transform(input, options = {}) {
|
|
return babel.transform(input, {
|
|
plugins: [[devExpressionWithCodes, options]],
|
|
}).code;
|
|
}
|
|
|
|
let oldEnv;
|
|
|
|
describe('error transform', () => {
|
|
beforeEach(() => {
|
|
oldEnv = process.env.NODE_ENV;
|
|
process.env.NODE_ENV = '';
|
|
});
|
|
|
|
afterEach(() => {
|
|
process.env.NODE_ENV = oldEnv;
|
|
});
|
|
|
|
it('should replace simple invariant calls', () => {
|
|
expect(
|
|
transform(`
|
|
import invariant from 'shared/invariant';
|
|
invariant(condition, 'Do not override existing functions.');
|
|
`)
|
|
).toMatchSnapshot();
|
|
});
|
|
|
|
it('should throw if invariant is not in an expression statement', () => {
|
|
expect(() => {
|
|
transform(`
|
|
import invariant from 'shared/invariant';
|
|
cond && invariant(condition, 'Do not override existing functions.');
|
|
`);
|
|
}).toThrow('invariant() cannot be called from expression context');
|
|
});
|
|
|
|
it('should support invariant calls with args', () => {
|
|
expect(
|
|
transform(`
|
|
import invariant from 'shared/invariant';
|
|
invariant(condition, 'Expected %s target to be an array; got %s', foo, bar);
|
|
`)
|
|
).toMatchSnapshot();
|
|
});
|
|
|
|
it('should support invariant calls with a concatenated template string and args', () => {
|
|
expect(
|
|
transform(`
|
|
import invariant from 'shared/invariant';
|
|
invariant(condition, 'Expected a component class, ' + 'got %s.' + '%s', Foo, Bar);
|
|
`)
|
|
).toMatchSnapshot();
|
|
});
|
|
|
|
it('should correctly transform invariants that are not in the error codes map', () => {
|
|
expect(
|
|
transform(`
|
|
import invariant from 'shared/invariant';
|
|
invariant(condition, 'This is not a real error message.');
|
|
`)
|
|
).toMatchSnapshot();
|
|
});
|
|
|
|
it('should handle escaped characters', () => {
|
|
expect(
|
|
transform(`
|
|
import invariant from 'shared/invariant';
|
|
invariant(condition, 'What\\'s up?');
|
|
`)
|
|
).toMatchSnapshot();
|
|
});
|
|
|
|
it('should support noMinify option', () => {
|
|
expect(
|
|
transform(
|
|
`
|
|
import invariant from 'shared/invariant';
|
|
invariant(condition, 'Do not override existing functions.');
|
|
`,
|
|
{noMinify: true}
|
|
)
|
|
).toMatchSnapshot();
|
|
});
|
|
});
|