From 875d05d5532b0e0b50faec6656a168cd9bb1a039 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 9 Apr 2019 16:40:19 -0700 Subject: [PATCH] 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`. --- scripts/error-codes/README.md | 2 +- ....snap => transform-error-messages.js.snap} | 11 +++++ ...essages.js => transform-error-messages.js} | 18 +++++-- ...essages.js => transform-error-messages.js} | 3 +- scripts/jest/preprocessor.js | 2 +- scripts/rollup/build.js | 9 +++- scripts/rollup/results.json | 48 +++++++++---------- 7 files changed, 61 insertions(+), 32 deletions(-) rename scripts/error-codes/__tests__/__snapshots__/{minify-error-messages.js.snap => transform-error-messages.js.snap} (90%) rename scripts/error-codes/__tests__/{minify-error-messages.js => transform-error-messages.js} (82%) rename scripts/error-codes/{minify-error-messages.js => transform-error-messages.js} (97%) diff --git a/scripts/error-codes/README.md b/scripts/error-codes/README.md index 2f39c9097e..27d9067cd2 100644 --- a/scripts/error-codes/README.md +++ b/scripts/error-codes/README.md @@ -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. diff --git a/scripts/error-codes/__tests__/__snapshots__/minify-error-messages.js.snap b/scripts/error-codes/__tests__/__snapshots__/transform-error-messages.js.snap similarity index 90% rename from scripts/error-codes/__tests__/__snapshots__/minify-error-messages.js.snap rename to scripts/error-codes/__tests__/__snapshots__/transform-error-messages.js.snap index 5227bf089c..54eb6ec99d 100644 --- a/scripts/error-codes/__tests__/__snapshots__/minify-error-messages.js.snap +++ b/scripts/error-codes/__tests__/__snapshots__/transform-error-messages.js.snap @@ -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.\`); + } +})();" +`; diff --git a/scripts/error-codes/__tests__/minify-error-messages.js b/scripts/error-codes/__tests__/transform-error-messages.js similarity index 82% rename from scripts/error-codes/__tests__/minify-error-messages.js rename to scripts/error-codes/__tests__/transform-error-messages.js index f9a799af45..f7caa79c30 100644 --- a/scripts/error-codes/__tests__/minify-error-messages.js +++ b/scripts/error-codes/__tests__/transform-error-messages.js @@ -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(); + }); }); diff --git a/scripts/error-codes/minify-error-messages.js b/scripts/error-codes/transform-error-messages.js similarity index 97% rename from scripts/error-codes/minify-error-messages.js rename to scripts/error-codes/transform-error-messages.js index 8a55ce4d4b..d83fdc4a59 100644 --- a/scripts/error-codes/minify-error-messages.js +++ b/scripts/error-codes/transform-error-messages.js @@ -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. diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js index 3a7b1448e5..d35f965499 100644 --- a/scripts/jest/preprocessor.js +++ b/scripts/jest/preprocessor.js @@ -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' diff --git a/scripts/rollup/build.js b/scripts/rollup/build.js index d21e58599e..486531ec99 100644 --- a/scripts/rollup/build.js +++ b/scripts/rollup/build.js @@ -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'), ]), diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index c858da46ff..6849341c1c 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -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",