Include full error messages in React Native build (#15363)

The React Native build does not minify error messages in production,
but it still needs to run the error messages transform to compile
`invariant` calls to `ReactError`. To do this, I added a `noMinify`
option to the Babel plugin. I also renamed it from
`minify-error-messages` to the more generic `transform-error-messages`.
This commit is contained in:
Andrew Clark 2019-04-09 16:40:19 -07:00 committed by GitHub
parent 1b2159acc3
commit 875d05d553
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 61 additions and 32 deletions

View File

@ -12,6 +12,6 @@ provide a better debugging support in production. Check out the blog post
can test it by running `yarn build -- --extract-errors`, but you should only
commit changes to this file when running a release. (The release tool will
perform this step automatically.)
- [`minify-error-codes`](https://github.com/facebook/react/blob/master/scripts/error-codes/minify-error-codes)
- [`transform-error-messages`](https://github.com/facebook/react/blob/master/scripts/error-codes/transform-error-messages)
is a Babel pass that rewrites error messages to IDs for a production
(minified) build.

View File

@ -94,3 +94,14 @@ import invariant from 'shared/invariant';
}
})();"
`;
exports[`error transform should support noMinify option 1`] = `
"import _ReactError from 'shared/ReactError';
import invariant from 'shared/invariant';
(function () {
if (!condition) {
throw _ReactError(\`Do not override existing functions.\`);
}
})();"
`;

View File

@ -8,11 +8,11 @@
'use strict';
let babel = require('babel-core');
let devExpressionWithCodes = require('../minify-error-messages');
let devExpressionWithCodes = require('../transform-error-messages');
function transform(input) {
function transform(input, options = {}) {
return babel.transform(input, {
plugins: [devExpressionWithCodes],
plugins: [[devExpressionWithCodes, options]],
}).code;
}
@ -82,4 +82,16 @@ 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();
});
});

View File

@ -19,6 +19,7 @@ module.exports = function(babel) {
visitor: {
CallExpression(path, file) {
const node = path.node;
const noMinify = file.opts.noMinify;
if (path.get('callee').isIdentifier({name: 'invariant'})) {
// Turns this code:
//
@ -66,7 +67,7 @@ module.exports = function(babel) {
const errorMap = invertObject(existingErrorMap);
let prodErrorId = errorMap[errorMsgLiteral];
if (prodErrorId === undefined) {
if (prodErrorId === undefined || noMinify) {
// There is no error code for this message. We use a lint rule to
// enforce that messages can be minified, so assume this is
// intentional and exit gracefully.

View File

@ -15,7 +15,7 @@ const pathToBabel = path.join(
'package.json'
);
const pathToBabelPluginDevWithCode = require.resolve(
'../error-codes/minify-error-messages'
'../error-codes/transform-error-messages'
);
const pathToBabelPluginWrapWarning = require.resolve(
'../babel/wrap-warning-with-env-check'

View File

@ -113,7 +113,7 @@ function getBabelConfig(updateBabelOptions, bundleType, filename) {
return Object.assign({}, options, {
plugins: options.plugins.concat([
// Minify invariant messages
require('../error-codes/minify-error-messages'),
require('../error-codes/transform-error-messages'),
// Wrap warning() calls in a __DEV__ check so they are stripped from production.
require('../babel/wrap-warning-with-env-check'),
]),
@ -126,6 +126,11 @@ function getBabelConfig(updateBabelOptions, bundleType, filename) {
case RN_FB_PROFILING:
return Object.assign({}, options, {
plugins: options.plugins.concat([
[
require('../error-codes/transform-error-messages'),
// Preserve full error messages in React Native build
{noMinify: true},
],
// Wrap warning() calls in a __DEV__ check so they are stripped from production.
require('../babel/wrap-warning-with-env-check'),
]),
@ -141,7 +146,7 @@ function getBabelConfig(updateBabelOptions, bundleType, filename) {
// Use object-assign polyfill in open source
path.resolve('./scripts/babel/transform-object-assign-require'),
// Minify invariant messages
require('../error-codes/minify-error-messages'),
require('../error-codes/transform-error-messages'),
// Wrap warning() calls in a __DEV__ check so they are stripped from production.
require('../babel/wrap-warning-with-env-check'),
]),

View File

@ -578,57 +578,57 @@
"filename": "ReactNativeRenderer-dev.js",
"bundleType": "RN_FB_DEV",
"packageName": "react-native-renderer",
"size": 645983,
"gzip": 137694
"size": 720540,
"gzip": 154199
},
{
"filename": "ReactNativeRenderer-prod.js",
"bundleType": "RN_FB_PROD",
"packageName": "react-native-renderer",
"size": 252030,
"gzip": 44064
"size": 252865,
"gzip": 44240
},
{
"filename": "ReactNativeRenderer-dev.js",
"bundleType": "RN_OSS_DEV",
"packageName": "react-native-renderer",
"size": 645895,
"gzip": 137660
"size": 720452,
"gzip": 154169
},
{
"filename": "ReactNativeRenderer-prod.js",
"bundleType": "RN_OSS_PROD",
"packageName": "react-native-renderer",
"size": 252044,
"gzip": 44061
"size": 252879,
"gzip": 44238
},
{
"filename": "ReactFabric-dev.js",
"bundleType": "RN_FB_DEV",
"packageName": "react-native-renderer",
"size": 634566,
"gzip": 134983
"size": 709123,
"gzip": 151511
},
{
"filename": "ReactFabric-prod.js",
"bundleType": "RN_FB_PROD",
"packageName": "react-native-renderer",
"size": 245276,
"gzip": 42773
"size": 246002,
"gzip": 42956
},
{
"filename": "ReactFabric-dev.js",
"bundleType": "RN_OSS_DEV",
"packageName": "react-native-renderer",
"size": 634470,
"gzip": 134930
"size": 709027,
"gzip": 151463
},
{
"filename": "ReactFabric-prod.js",
"bundleType": "RN_OSS_PROD",
"packageName": "react-native-renderer",
"size": 245282,
"gzip": 42767
"size": 246008,
"gzip": 42950
},
{
"filename": "ReactTestRenderer-dev.js",
@ -725,15 +725,15 @@
"filename": "ReactNativeRenderer-profiling.js",
"bundleType": "RN_OSS_PROFILING",
"packageName": "react-native-renderer",
"size": 258447,
"gzip": 45443
"size": 259040,
"gzip": 45588
},
{
"filename": "ReactFabric-profiling.js",
"bundleType": "RN_OSS_PROFILING",
"packageName": "react-native-renderer",
"size": 250755,
"gzip": 44122
"size": 251432,
"gzip": 44320
},
{
"filename": "Scheduler-dev.js",
@ -774,15 +774,15 @@
"filename": "ReactNativeRenderer-profiling.js",
"bundleType": "RN_FB_PROFILING",
"packageName": "react-native-renderer",
"size": 258428,
"gzip": 45445
"size": 259021,
"gzip": 45590
},
{
"filename": "ReactFabric-profiling.js",
"bundleType": "RN_FB_PROFILING",
"packageName": "react-native-renderer",
"size": 250744,
"gzip": 44126
"size": 251421,
"gzip": 44324
},
{
"filename": "react.profiling.min.js",