From 27cab88e416e97ab3e16122821d258c73a9e77b8 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 9 Apr 2019 16:29:47 -0700 Subject: [PATCH] Include full error messages in React Native build 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 2f39c9097ee1..27d9067cd299 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 5227bf089c45..54eb6ec99dbc 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 f9a799af4528..f7caa79c3068 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 8a55ce4d4bbc..d83fdc4a5984 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 3a7b1448e505..d35f96549967 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 d21e58599ece..486531ec99c4 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 c858da46fff8..6849341c1c03 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",