Skip to content

Commit b2e38a9

Browse files
committed
Replace old extract-errors script with new one
Deletes the old extract-errors in favor of extract-errors2
1 parent 24feb63 commit b2e38a9

File tree

6 files changed

+63
-187
lines changed

6 files changed

+63
-187
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ jobs:
221221
- run:
222222
name: Search build artifacts for unminified errors
223223
command: |
224-
yarn extract-errors2
224+
yarn extract-errors
225225
git diff || (echo "Found unminified errors. Either update the error codes map or disable error minification for the affected build, if appropriate." && false)
226226
227227
yarn_test:

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@
114114
"linc": "node ./scripts/tasks/linc.js",
115115
"lint": "node ./scripts/tasks/eslint.js",
116116
"lint-build": "node ./scripts/rollup/validate/index.js",
117-
"extract-errors": "yarn build --type=dev --extract-errors",
118-
"extract-errors2": "node scripts/error-codes/extract-errors2.js",
117+
"extract-errors": "node scripts/error-codes/extract-errors.js",
119118
"postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js && node ./scripts/yarn/downloadReactIsForPrettyFormat.js",
120119
"debug-test": "yarn test --deprecated 'yarn test --debug'",
121120
"test": "node ./scripts/jest/jest-cli.js",

scripts/error-codes/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ provide a better debugging support in production. Check out the blog post
99
the file will never be changed/removed.
1010
- [`extract-errors.js`](https://github.com/facebook/react/blob/main/scripts/error-codes/extract-errors.js)
1111
is an node script that traverses our codebase and updates `codes.json`. You
12-
can test it by running `yarn extract-errors`.
12+
can test it by running `yarn extract-errors`. It works by crawling the build
13+
artifacts directory, so you need to have either run the build script or
14+
downloaded pre-built artifacts (e.g. with `yarn download build`). It works
15+
with partial builds, too.
1316
- [`transform-error-messages`](https://github.com/facebook/react/blob/main/scripts/error-codes/transform-error-messages.js)
1417
is a Babel pass that rewrites error messages to IDs for a production
1518
(minified) build.

scripts/error-codes/extract-errors.js

Lines changed: 56 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,74 @@
1-
/**
2-
* Copyright (c) Facebook, Inc. and its affiliates.
3-
*
4-
* This source code is licensed under the MIT license found in the
5-
* LICENSE file in the root directory of this source tree.
6-
*/
71
'use strict';
82

9-
const parser = require('@babel/parser');
103
const fs = require('fs');
114
const path = require('path');
12-
const traverse = require('@babel/traverse').default;
13-
const {evalStringConcat} = require('../shared/evalToString');
14-
const invertObject = require('./invertObject');
5+
const {execSync} = require('child_process');
156

16-
const babylonOptions = {
17-
sourceType: 'module',
18-
// As a parser, babylon has its own options and we can't directly
19-
// import/require a babel preset. It should be kept **the same** as
20-
// the `babel-plugin-syntax-*` ones specified in
21-
// https://github.com/facebook/fbjs/blob/master/packages/babel-preset-fbjs/configure.js
22-
plugins: [
23-
'classProperties',
24-
'flow',
25-
'jsx',
26-
'trailingFunctionCommas',
27-
'objectRestSpread',
28-
],
29-
};
30-
31-
module.exports = function(opts) {
32-
if (!opts || !('errorMapFilePath' in opts)) {
33-
throw new Error(
34-
'Missing options. Ensure you pass an object with `errorMapFilePath`.'
35-
);
7+
async function main() {
8+
const originalJSON = JSON.parse(
9+
fs.readFileSync(path.resolve(__dirname, '../error-codes/codes.json'))
10+
);
11+
const existingMessages = new Set();
12+
const codes = Object.keys(originalJSON);
13+
let nextCode = 0;
14+
for (let i = 0; i < codes.length; i++) {
15+
const codeStr = codes[i];
16+
const message = originalJSON[codeStr];
17+
const code = parseInt(codeStr, 10);
18+
existingMessages.add(message);
19+
if (code >= nextCode) {
20+
nextCode = code + 1;
21+
}
3622
}
3723

38-
const errorMapFilePath = opts.errorMapFilePath;
39-
let existingErrorMap;
24+
console.log('Searching `build` directory for unminified errors...\n');
25+
26+
let out;
4027
try {
41-
// Using `fs.readFileSync` instead of `require` here, because `require()`
42-
// calls are cached, and the cache map is not properly invalidated after
43-
// file changes.
44-
existingErrorMap = JSON.parse(
45-
fs.readFileSync(
46-
path.join(__dirname, path.basename(errorMapFilePath)),
47-
'utf8'
48-
)
49-
);
28+
out = execSync(
29+
"git --no-pager grep -n --untracked --no-exclude-standard '/*! <expected-error-format>' -- build"
30+
).toString();
5031
} catch (e) {
51-
existingErrorMap = {};
52-
}
53-
54-
const allErrorIDs = Object.keys(existingErrorMap);
55-
let currentID;
56-
57-
if (allErrorIDs.length === 0) {
58-
// Map is empty
59-
currentID = 0;
60-
} else {
61-
currentID = Math.max.apply(null, allErrorIDs) + 1;
32+
if (e.status === 1 && e.stdout.toString() === '') {
33+
// No unminified errors found.
34+
return;
35+
}
36+
throw e;
6237
}
6338

64-
// Here we invert the map object in memory for faster error code lookup
65-
existingErrorMap = invertObject(existingErrorMap);
66-
67-
function transform(source) {
68-
const ast = parser.parse(source, babylonOptions);
69-
70-
traverse(ast, {
71-
CallExpression: {
72-
exit(astPath) {
73-
if (astPath.get('callee').isIdentifier({name: 'invariant'})) {
74-
const node = astPath.node;
39+
let newJSON = null;
40+
const regex = /\<expected-error-format\>"(.+?)"\<\/expected-error-format\>/g;
41+
do {
42+
const match = regex.exec(out);
43+
if (match === null) {
44+
break;
45+
} else {
46+
const message = match[1].trim();
47+
if (existingMessages.has(message)) {
48+
// This probably means you ran the script twice.
49+
continue;
50+
}
51+
existingMessages.add(message);
7552

76-
// error messages can be concatenated (`+`) at runtime, so here's a
77-
// trivial partial evaluator that interprets the literal value
78-
const errorMsgLiteral = evalStringConcat(node.arguments[1]);
79-
addToErrorMap(errorMsgLiteral);
80-
}
81-
},
82-
},
83-
});
84-
}
85-
86-
function addToErrorMap(errorMsgLiteral) {
87-
if (existingErrorMap.hasOwnProperty(errorMsgLiteral)) {
88-
return;
53+
// Add to json map
54+
if (newJSON === null) {
55+
newJSON = Object.assign({}, originalJSON);
56+
}
57+
console.log(`"${nextCode}": "${message}"`);
58+
newJSON[nextCode] = message;
59+
nextCode += 1;
8960
}
90-
existingErrorMap[errorMsgLiteral] = '' + currentID++;
91-
}
61+
} while (true);
9262

93-
function flush(cb) {
63+
if (newJSON) {
9464
fs.writeFileSync(
95-
errorMapFilePath,
96-
JSON.stringify(invertObject(existingErrorMap), null, 2) + '\n',
97-
'utf-8'
65+
path.resolve(__dirname, '../error-codes/codes.json'),
66+
JSON.stringify(newJSON, null, 2)
9867
);
9968
}
69+
}
10070

101-
return function extractErrors(source) {
102-
transform(source);
103-
flush();
104-
};
105-
};
71+
main().catch(error => {
72+
console.error(error);
73+
process.exit(1);
74+
});

scripts/error-codes/extract-errors2.js

Lines changed: 0 additions & 74 deletions
This file was deleted.

scripts/rollup/build.js

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const Sync = require('./sync');
1919
const sizes = require('./plugins/sizes-plugin');
2020
const useForks = require('./plugins/use-forks-plugin');
2121
const stripUnusedImports = require('./plugins/strip-unused-imports');
22-
const extractErrorCodes = require('../error-codes/extract-errors');
2322
const Packaging = require('./packaging');
2423
const {asyncRimRaf} = require('./utils');
2524
const codeFrame = require('babel-code-frame');
@@ -94,10 +93,6 @@ const forcePrettyOutput = argv.pretty;
9493
const isWatchMode = argv.watch;
9594
const syncFBSourcePath = argv['sync-fbsource'];
9695
const syncWWWPath = argv['sync-www'];
97-
const shouldExtractErrors = argv['extract-errors'];
98-
const errorCodeOpts = {
99-
errorMapFilePath: 'scripts/error-codes/codes.json',
100-
};
10196

10297
const closureOptions = {
10398
compilation_level: 'SIMPLE',
@@ -324,7 +319,6 @@ function getPlugins(
324319
pureExternalModules,
325320
bundle
326321
) {
327-
const findAndRecordErrorCodes = extractErrorCodes(errorCodeOpts);
328322
const forks = Modules.getForks(bundleType, entry, moduleType, bundle);
329323
const isProduction = isProductionBundleType(bundleType);
330324
const isProfiling = isProfilingBundleType(bundleType);
@@ -345,13 +339,6 @@ function getPlugins(
345339
bundleType === RN_FB_PROFILING;
346340
const shouldStayReadable = isFBWWWBundle || isRNBundle || forcePrettyOutput;
347341
return [
348-
// Extract error codes from invariant() messages into a file.
349-
shouldExtractErrors && {
350-
transform(source) {
351-
findAndRecordErrorCodes(source);
352-
return source;
353-
},
354-
},
355342
// Shim any modules that need forking in this environment.
356343
useForks(forks),
357344
// Ensure we don't try to bundle any fbjs modules.
@@ -747,7 +734,7 @@ async function buildEverything() {
747734
);
748735
}
749736

750-
if (!shouldExtractErrors && process.env.CIRCLE_NODE_TOTAL) {
737+
if (process.env.CIRCLE_NODE_TOTAL) {
751738
// In CI, parallelize bundles across multiple tasks.
752739
const nodeTotal = parseInt(process.env.CIRCLE_NODE_TOTAL, 10);
753740
const nodeIndex = parseInt(process.env.CIRCLE_NODE_INDEX, 10);
@@ -772,14 +759,6 @@ async function buildEverything() {
772759
if (!forcePrettyOutput) {
773760
Stats.saveResults();
774761
}
775-
776-
if (shouldExtractErrors) {
777-
console.warn(
778-
'\nWarning: this build was created with --extract-errors enabled.\n' +
779-
'this will result in extremely slow builds and should only be\n' +
780-
'used when the error map needs to be rebuilt.\n'
781-
);
782-
}
783762
}
784763

785764
buildEverything();

0 commit comments

Comments
 (0)