Skip to content

Commit

Permalink
fix(build): move error-codes generation to transform-error-messages b…
Browse files Browse the repository at this point in the history
…abel plugin and always run with build-release
  • Loading branch information
etrepum committed May 2, 2024
1 parent 6bb75a4 commit a9b91aa
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 136 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
"build": "node scripts/build.js",
"build-prod": "npm run clean && npm run build -- --prod",
"build-playground-prod": "npm run build-prod && npm run build-prod --prefix packages/lexical-playground",
"build-release": "npm run build-prod -- --release",
"build-release": "npm run build-prod -- --release --codes",
"build-www": "npm run clean && npm run build -- --www && npm run build -- --www --prod && npm run prepare-www",
"build-types": "tsc -p ./tsconfig.build.json && node ./scripts/validate-tsc-types.js",
"clean": "node scripts/clean.js",
"extract-codes": "node scripts/build.js --codes",
"flow": "node ./scripts/check-flow-types.js",
"tsc": "tsc",
"tsc-extension": "npm run compile -w @lexical/devtools",
Expand Down
11 changes: 6 additions & 5 deletions packages/lexical-website/docs/maintainers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ This runs all of the pre-release steps and will let you inspect the artifacts
that would be uploaded to npm. Each public package will have a npm directory, e.g.
`packages/lexical/npm` that contains those artifacts.

This will also update scripts/error-codes/codes.json, the mapping of
production error codes to error messages. It's imperative to commit the result
of this before tagging a release.

### npm run ci-check

Check flow, TypeScript, prettier and eslint for issues. A good command to run
Expand Down Expand Up @@ -227,11 +231,8 @@ Run eslint
### npm run increment-version

Increment the monorepo version. Make sure to run `npm run update-packages`
after this.

### npm run extract-codes

Extract error codes for the production build. Essential to run before a release.
(to update all examples and sub-packages) and `npm run prepare-release`
(to update `scripts/error-codes/codes.json`) after this.

### npm run changelog

Expand Down
17 changes: 1 addition & 16 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const nodeResolve = require('@rollup/plugin-node-resolve').default;
const commonjs = require('@rollup/plugin-commonjs');
const replace = require('@rollup/plugin-replace');
const json = require('@rollup/plugin-json');
const extractErrorCodes = require('./error-codes/extract-errors');
const alias = require('@rollup/plugin-alias');
const compiler = require('@ampproject/rollup-plugin-closure-compiler');
const terser = require('@rollup/plugin-terser');
Expand Down Expand Up @@ -103,12 +102,6 @@ const externals = [
'y-websocket',
].sort();

const errorCodeOpts = {
errorMapFilePath: 'scripts/error-codes/codes.json',
};

const findAndRecordErrorCodes = extractErrorCodes(errorCodeOpts);

const strictWWWMappings = {};

// Add quotes around mappings to make them more strict.
Expand Down Expand Up @@ -175,14 +168,6 @@ async function build(name, inputFile, outputPath, outputFile, isProd, format) {
{find: 'shared', replacement: path.resolve('packages/shared/src')},
],
}),
// Extract error codes from invariant() messages into a file.
{
transform(source) {
// eslint-disable-next-line no-unused-expressions
extractCodes && findAndRecordErrorCodes(source);
return source;
},
},
nodeResolve({
extensions,
}),
Expand All @@ -195,7 +180,7 @@ async function build(name, inputFile, outputPath, outputFile, isProd, format) {
plugins: [
[
require('./error-codes/transform-error-messages'),
{noMinify: !isProd},
{extractCodes, noMinify: !isProd},
],
'@babel/plugin-transform-optional-catch-binding',
],
Expand Down
104 changes: 0 additions & 104 deletions scripts/error-codes/extract-errors.js

This file was deleted.

82 changes: 73 additions & 9 deletions scripts/error-codes/transform-error-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,85 @@
*/

'use strict';
// @ts-check

const fs = require('fs-extra');
const evalToString = require('./evalToString');
const invertObject = require('./invertObject');
const helperModuleImports = require('@babel/helper-module-imports');
const prettier = require('prettier');

module.exports = function (babel) {
const t = babel.types;
class ErrorMap {
/** @type {Record<string, string>} */
errorMap;
/** @type {Record<string, number} */
inverseErrorMap = {};
/** @type {number} */
maxId = -1;
/** @type {boolean} */
dirty = false;

/**
* @param {Record<string, string>} errorMap
* @param {(errorMap: Record<string, string>) => void} flushErrorMap
*/
constructor(errorMap, flushErrorMap) {
this.errorMap = errorMap;
this.flushErrorMap = flushErrorMap;
for (const k in this.errorMap) {
const id = parseInt(k, 10);
this.inverseErrorMap[this.errorMap[k]] = id;
this.maxId = id > this.maxId ? id : this.maxId;
}
}

/**
* @param {string} message
* @param {boolean} extractCodes true if we are also writing to codes.json
* @returns {number | undefined}
*/
getOrAddToErrorMap(message, extractCodes) {
let id = this.inverseErrorMap[message];
if (extractCodes && typeof id === 'undefined') {
id = ++this.maxId;
this.inverseErrorMap[message] = id;
this.errorMap[`${id}`] = message;
if (!this.dirty) {
queueMicrotask(this.flush.bind(this));
this.dirty = true;
}
}
return id;
}

flush() {
if (this.dirty) {
this.flushErrorMap(this.errorMap);
this.dirty = false;
}
}
}

/**
* @returns {Promise<import('@babel/core').PluginObj>}
*/
module.exports = async function (babel) {
const t = babel.types;
const filepath = `${__dirname}/codes.json`;
const prettierConfig = {
...((await prettier.resolveConfig('./')) || {}),
filepath,
};
const errorMap = new ErrorMap(fs.readJsonSync(filepath), (newErrorMap) =>
fs.writeFileSync(
filepath,
prettier.format(JSON.stringify(newErrorMap), prettierConfig),
),
);
return {
visitor: {
CallExpression(path, file) {
const node = path.node;
const noMinify = file.opts.noMinify;
const {extractCodes, noMinify} = file.opts;
if (path.get('callee').isIdentifier({name: 'invariant'})) {
// Turns this code:
//
Expand Down Expand Up @@ -82,10 +147,10 @@ module.exports = function (babel) {
}

// Avoid caching because we write it as we go.
const existingErrorMap = fs.readJsonSync(__dirname + '/codes.json');
const errorMap = invertObject(existingErrorMap);

let prodErrorId = errorMap[errorMsgLiteral];
let prodErrorId = errorMap.getOrAddToErrorMap(
errorMsgLiteral,
extractCodes,
);

if (prodErrorId === undefined) {
// There is no error code for this message. Add an inline comment
Expand Down Expand Up @@ -113,7 +178,6 @@ module.exports = function (babel) {
);
return;
}
prodErrorId = parseInt(prodErrorId, 10);

// Import ReactErrorProd
const formatProdErrorMessageIdentifier =
Expand Down

0 comments on commit a9b91aa

Please sign in to comment.