diff --git a/compiler/apps/playground/package.json b/compiler/apps/playground/package.json
index c3dd825f1a16f..9b43f18f0e8c4 100644
--- a/compiler/apps/playground/package.json
+++ b/compiler/apps/playground/package.json
@@ -3,10 +3,11 @@
"version": "0.1.0",
"private": true,
"scripts": {
- "dev": "cd ../.. && concurrently --kill-others -n compiler,runtime,playground \"yarn workspace babel-plugin-react-compiler run build --watch\" \"yarn workspace react-compiler-runtime run build --watch\" \"wait-on packages/babel-plugin-react-compiler/dist/index.js && cd apps/playground && NODE_ENV=development next dev\"",
+ "dev": "cd ../.. && concurrently --kill-others -n compiler,runtime,playground \"yarn workspace babel-plugin-react-compiler run watch\" \"yarn workspace react-compiler-runtime run watch\" \"wait-on packages/babel-plugin-react-compiler/dist/index.js && cd apps/playground && NODE_ENV=development next dev\"",
"build:compiler": "cd ../.. && concurrently -n compiler,runtime \"yarn workspace babel-plugin-react-compiler run build\" \"yarn workspace react-compiler-runtime run build\"",
"build": "yarn build:compiler && next build",
"postbuild": "node ./scripts/downloadFonts.js",
+ "preinstall": "cd ../.. && yarn install --frozen-lockfile",
"postinstall": "./scripts/link-compiler.sh",
"vercel-build": "yarn build",
"start": "next start",
diff --git a/compiler/package.json b/compiler/package.json
index b25031b9967d8..05e3b6c5abe87 100644
--- a/compiler/package.json
+++ b/compiler/package.json
@@ -15,7 +15,7 @@
"start": "yarn workspace playground run start",
"next": "yarn workspace playground run dev",
"build": "yarn workspaces run build",
- "dev": "echo 'DEPRECATED: use `cd apps/playground && yarn dev` instead!' && sleep 5 && cd apps/playground && yarn dev",
+ "dev": "cd apps/playground && yarn dev",
"test": "yarn workspaces run test",
"snap": "yarn workspace babel-plugin-react-compiler run snap",
"snap:build": "yarn workspace snap run build",
@@ -26,22 +26,15 @@
"react-is": "0.0.0-experimental-4beb1fd8-20241118"
},
"devDependencies": {
- "@rollup/plugin-commonjs": "^28.0.2",
- "@rollup/plugin-json": "^6.1.0",
- "@rollup/plugin-node-resolve": "^16.0.0",
- "@rollup/plugin-terser": "^0.4.4",
- "@rollup/plugin-typescript": "^12.1.2",
"@tsconfig/strictest": "^2.0.5",
"concurrently": "^7.4.0",
+ "esbuild": "^0.24.2",
"folder-hash": "^4.0.4",
"object-assign": "^4.1.1",
"ora": "5.4.1",
"prettier": "^3.3.3",
- "prettier-plugin-hermes-parser": "^0.25.1",
+ "prettier-plugin-hermes-parser": "^0.26.0",
"prompt-promise": "^1.0.3",
- "rollup": "^4.22.4",
- "rollup-plugin-banner2": "^1.2.3",
- "rollup-plugin-prettier": "^4.1.1",
"typescript": "^5.4.3",
"wait-on": "^7.2.0",
"yargs": "^17.7.2"
diff --git a/compiler/packages/babel-plugin-react-compiler/package.json b/compiler/packages/babel-plugin-react-compiler/package.json
index 158b800dba900..eb6c3cc628eb2 100644
--- a/compiler/packages/babel-plugin-react-compiler/package.json
+++ b/compiler/packages/babel-plugin-react-compiler/package.json
@@ -9,14 +9,15 @@
"!*.tsbuildinfo"
],
"scripts": {
- "build": "rimraf dist && rollup --config --bundleConfigAsCjs",
+ "build": "rimraf dist && scripts/build.js",
"test": "./scripts/link-react-compiler-runtime.sh && yarn snap:ci",
"jest": "yarn build && ts-node node_modules/.bin/jest",
"snap": "node ../snap/dist/main.js",
"snap:build": "yarn workspace snap run build",
"snap:ci": "yarn snap:build && yarn snap",
"ts:analyze-trace": "scripts/ts-analyze-trace.sh",
- "lint": "yarn eslint src"
+ "lint": "yarn eslint src",
+ "watch": "scripts/build.js --watch"
},
"dependencies": {
"@babel/types": "^7.19.0"
diff --git a/compiler/packages/babel-plugin-react-compiler/rollup.config.js b/compiler/packages/babel-plugin-react-compiler/rollup.config.js
deleted file mode 100644
index b95cc89b39b13..0000000000000
--- a/compiler/packages/babel-plugin-react-compiler/rollup.config.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import typescript from '@rollup/plugin-typescript';
-import {nodeResolve} from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
-import json from '@rollup/plugin-json';
-import path from 'path';
-import process from 'process';
-import terser from '@rollup/plugin-terser';
-import prettier from 'rollup-plugin-prettier';
-import banner2 from 'rollup-plugin-banner2';
-
-const NO_INLINE = new Set(['@babel/types']);
-
-const DEV_ROLLUP_CONFIG = {
- input: 'src/index.ts',
- output: {
- file: 'dist/index.js',
- format: 'cjs',
- sourcemap: false,
- exports: 'named',
- inlineDynamicImports: true,
- },
- plugins: [
- typescript({
- tsconfig: './tsconfig.json',
- outputToFilesystem: true,
- compilerOptions: {
- noEmit: true,
- },
- }),
- json(),
- nodeResolve({
- preferBuiltins: true,
- resolveOnly: module => NO_INLINE.has(module) === false,
- rootDir: path.join(process.cwd(), '..'),
- }),
- commonjs(),
- terser({
- format: {
- comments: false,
- },
- compress: false,
- mangle: false,
- }),
- prettier(),
- banner2(
- () => `/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @lightSyntaxTransform
- * @noflow
- * @nolint
- * @preventMunge
- * @preserve-invariant-messages
- */
-
-"use no memo";
-`
- ),
- ],
-};
-
-export default DEV_ROLLUP_CONFIG;
diff --git a/compiler/packages/babel-plugin-react-compiler/scripts/build.js b/compiler/packages/babel-plugin-react-compiler/scripts/build.js
new file mode 100755
index 0000000000000..5c451f11f99f9
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/scripts/build.js
@@ -0,0 +1,61 @@
+#!/usr/bin/env node
+
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const esbuild = require('esbuild');
+const yargs = require('yargs');
+const path = require('path');
+
+const argv = yargs(process.argv.slice(2))
+ .options('w', {
+ alias: 'watch',
+ default: false,
+ type: 'boolean',
+ })
+ .parse();
+
+const config = {
+ entryPoints: [path.join(__dirname, '../src/index.ts')],
+ outfile: path.join(__dirname, '../dist/index.js'),
+ bundle: true,
+ external: ['@babel/types'],
+ format: 'cjs',
+ platform: 'node',
+ banner: {
+ js: `/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @lightSyntaxTransform
+ * @noflow
+ * @nolint
+ * @preventMunge
+ * @preserve-invariant-messages
+ */
+
+"use no memo";`,
+ },
+};
+
+async function main() {
+ if (argv.w) {
+ const ctx = await esbuild.context(config);
+ await ctx.watch();
+ console.log('watching for changes...');
+ } else {
+ await esbuild.build({
+ sourcemap: true,
+ minify: false,
+ ...config,
+ });
+ }
+}
+
+main();
diff --git a/compiler/packages/eslint-plugin-react-compiler/package.json b/compiler/packages/eslint-plugin-react-compiler/package.json
index eec2c9424846a..d325b3f3d1c67 100644
--- a/compiler/packages/eslint-plugin-react-compiler/package.json
+++ b/compiler/packages/eslint-plugin-react-compiler/package.json
@@ -4,8 +4,9 @@
"description": "ESLint plugin to display errors found by the React compiler.",
"main": "dist/index.js",
"scripts": {
- "build": "rimraf dist && rollup --config --bundleConfigAsCjs",
- "test": "tsc && jest"
+ "build": "rimraf dist && scripts/build.js",
+ "test": "tsc && jest",
+ "watch": "scripts/build.js --watch"
},
"files": [
"dist"
diff --git a/compiler/packages/eslint-plugin-react-compiler/rollup.config.js b/compiler/packages/eslint-plugin-react-compiler/rollup.config.js
deleted file mode 100644
index 743e4cc844102..0000000000000
--- a/compiler/packages/eslint-plugin-react-compiler/rollup.config.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import typescript from '@rollup/plugin-typescript';
-import {nodeResolve} from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
-import json from '@rollup/plugin-json';
-import path from 'path';
-import process from 'process';
-import terser from '@rollup/plugin-terser';
-import prettier from 'rollup-plugin-prettier';
-import banner2 from 'rollup-plugin-banner2';
-
-const NO_INLINE = new Set([
- '@babel/core',
- '@babel/plugin-proposal-private-methods',
- 'hermes-parser',
- 'zod',
- 'zod-validation-error',
-]);
-
-const DEV_ROLLUP_CONFIG = {
- input: 'src/index.ts',
- output: {
- file: 'dist/index.js',
- format: 'cjs',
- sourcemap: false,
- inlineDynamicImports: true,
- },
- treeshake: {
- moduleSideEffects: false,
- },
- plugins: [
- typescript({
- compilerOptions: {
- noEmit: true,
- },
- }),
- json(),
- nodeResolve({
- preferBuiltins: true,
- resolveOnly: module => NO_INLINE.has(module) === false,
- rootDir: path.join(process.cwd(), '..'),
- }),
- commonjs(),
- terser({
- format: {
- comments: false,
- },
- compress: false,
- mangle: false,
- }),
- prettier(),
- banner2(
- () => `/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @lightSyntaxTransform
- * @noflow
- * @nolint
- * @preventMunge
- * @preserve-invariant-messages
- */
-
-"use no memo";
-`
- ),
- ],
-};
-
-export default DEV_ROLLUP_CONFIG;
diff --git a/compiler/packages/eslint-plugin-react-compiler/scripts/build.js b/compiler/packages/eslint-plugin-react-compiler/scripts/build.js
new file mode 100755
index 0000000000000..d201f38b89570
--- /dev/null
+++ b/compiler/packages/eslint-plugin-react-compiler/scripts/build.js
@@ -0,0 +1,67 @@
+#!/usr/bin/env node
+
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const esbuild = require('esbuild');
+const yargs = require('yargs');
+const path = require('path');
+
+const argv = yargs(process.argv.slice(2))
+ .options('w', {
+ alias: 'watch',
+ default: false,
+ type: 'boolean',
+ })
+ .parse();
+
+const config = {
+ entryPoints: [path.join(__dirname, '../src/index.ts')],
+ outfile: path.join(__dirname, '../dist/index.js'),
+ bundle: true,
+ external: [
+ '@babel/core',
+ '@babel/plugin-proposal-private-methods',
+ 'hermes-parser',
+ 'zod',
+ 'zod-validation-error',
+ ],
+ format: 'cjs',
+ platform: 'node',
+ banner: {
+ js: `/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @lightSyntaxTransform
+ * @noflow
+ * @nolint
+ * @preventMunge
+ * @preserve-invariant-messages
+ */
+
+"use no memo";`,
+ },
+};
+
+async function main() {
+ if (argv.w) {
+ const ctx = await esbuild.context(config);
+ await ctx.watch();
+ console.log('watching for changes...');
+ } else {
+ await esbuild.build({
+ sourcemap: true,
+ minify: false,
+ ...config,
+ });
+ }
+}
+
+main();
diff --git a/compiler/packages/make-read-only-util/package.json b/compiler/packages/make-read-only-util/package.json
index 212d934669d5d..59293c1771c0b 100644
--- a/compiler/packages/make-read-only-util/package.json
+++ b/compiler/packages/make-read-only-util/package.json
@@ -1,12 +1,14 @@
{
"name": "make-read-only-util",
"version": "0.0.1",
+ "license": "MIT",
"files": [
"src"
],
"scripts": {
- "build": "tsc",
- "test": "jest src"
+ "build": "rimraf dist && scripts/build.js",
+ "test": "jest src",
+ "watch": "scripts/build.js --watch"
},
"dependencies": {
"invariant": "^2.2.4",
diff --git a/compiler/packages/make-read-only-util/scripts/build.js b/compiler/packages/make-read-only-util/scripts/build.js
new file mode 100755
index 0000000000000..91301c3b6a0f2
--- /dev/null
+++ b/compiler/packages/make-read-only-util/scripts/build.js
@@ -0,0 +1,61 @@
+#!/usr/bin/env node
+
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const esbuild = require('esbuild');
+const yargs = require('yargs');
+const path = require('path');
+
+const argv = yargs(process.argv.slice(2))
+ .options('w', {
+ alias: 'watch',
+ default: false,
+ type: 'boolean',
+ })
+ .parse();
+
+const config = {
+ entryPoints: [path.join(__dirname, '../src/makeReadOnly.ts')],
+ outfile: path.join(__dirname, '../dist/index.js'),
+ bundle: true,
+ format: 'esm',
+ platform: 'browser',
+ target: 'es6',
+ banner: {
+ js: `/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @lightSyntaxTransform
+ * @noflow
+ * @nolint
+ * @preventMunge
+ * @preserve-invariant-messages
+ */
+
+"use no memo";`,
+ },
+};
+
+async function main() {
+ if (argv.w) {
+ const ctx = await esbuild.context(config);
+ await ctx.watch();
+ console.log('watching for changes...');
+ } else {
+ await esbuild.build({
+ sourcemap: true,
+ minify: false,
+ ...config,
+ });
+ }
+}
+
+main();
diff --git a/compiler/packages/react-compiler-healthcheck/package.json b/compiler/packages/react-compiler-healthcheck/package.json
index 673e18d8ebb34..44a52151bbbb4 100644
--- a/compiler/packages/react-compiler-healthcheck/package.json
+++ b/compiler/packages/react-compiler-healthcheck/package.json
@@ -6,8 +6,9 @@
"react-compiler-healthcheck": "dist/index.js"
},
"scripts": {
- "build": "rimraf dist && rollup --config --bundleConfigAsCjs",
- "test": "echo 'no tests'"
+ "build": "rimraf dist && scripts/build.js",
+ "test": "echo 'no tests'",
+ "watch": "scripts/build.js --watch"
},
"dependencies": {
"@babel/core": "^7.24.4",
diff --git a/compiler/packages/react-compiler-healthcheck/rollup.config.js b/compiler/packages/react-compiler-healthcheck/rollup.config.js
deleted file mode 100644
index 0c2492d14069d..0000000000000
--- a/compiler/packages/react-compiler-healthcheck/rollup.config.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import typescript from '@rollup/plugin-typescript';
-import {nodeResolve} from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
-import json from '@rollup/plugin-json';
-import path from 'path';
-import process from 'process';
-import terser from '@rollup/plugin-terser';
-import prettier from 'rollup-plugin-prettier';
-import banner2 from 'rollup-plugin-banner2';
-
-const NO_INLINE = new Set([
- '@babel/core',
- '@babel/parser',
- 'chalk',
- 'fast-glob',
- 'ora',
- 'yargs',
- 'zod',
- 'zod-validation-error',
-]);
-
-const DEV_ROLLUP_CONFIG = {
- input: 'src/index.ts',
- output: {
- file: 'dist/index.js',
- format: 'cjs',
- sourcemap: false,
- exports: 'named',
- inlineDynamicImports: true,
- },
- plugins: [
- typescript({
- tsconfig: './tsconfig.json',
- compilerOptions: {
- noEmit: true,
- },
- }),
- json(),
- nodeResolve({
- preferBuiltins: true,
- resolveOnly: module => NO_INLINE.has(module) === false,
- rootDir: path.join(process.cwd(), '..'),
- }),
- commonjs(),
- terser({
- format: {
- comments: false,
- },
- compress: false,
- mangle: false,
- }),
- prettier(),
- banner2(
- () => `#!/usr/bin/env node
-
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @lightSyntaxTransform
- * @noflow
- * @nolint
- * @preventMunge
- * @preserve-invariant-messages
- */
-
-"use no memo";
-`
- ),
- ],
-};
-
-export default DEV_ROLLUP_CONFIG;
diff --git a/compiler/packages/react-compiler-healthcheck/scripts/build.js b/compiler/packages/react-compiler-healthcheck/scripts/build.js
new file mode 100755
index 0000000000000..b8e0f88d6c8a5
--- /dev/null
+++ b/compiler/packages/react-compiler-healthcheck/scripts/build.js
@@ -0,0 +1,70 @@
+#!/usr/bin/env node
+
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const esbuild = require('esbuild');
+const yargs = require('yargs');
+const path = require('path');
+
+const argv = yargs(process.argv.slice(2))
+ .options('w', {
+ alias: 'watch',
+ default: false,
+ type: 'boolean',
+ })
+ .parse();
+
+const config = {
+ entryPoints: [path.join(__dirname, '../src/index.ts')],
+ outfile: path.join(__dirname, '../dist/index.js'),
+ bundle: true,
+ external: [
+ '@babel/core',
+ '@babel/parser',
+ 'chalk',
+ 'fast-glob',
+ 'ora',
+ 'yargs',
+ 'zod',
+ 'zod-validation-error',
+ ],
+ format: 'cjs',
+ platform: 'node',
+ banner: {
+ js: `/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @lightSyntaxTransform
+ * @noflow
+ * @nolint
+ * @preventMunge
+ * @preserve-invariant-messages
+ */
+
+"use no memo";`,
+ },
+};
+
+async function main() {
+ if (argv.w) {
+ const ctx = await esbuild.context(config);
+ await ctx.watch();
+ console.log('watching for changes...');
+ } else {
+ await esbuild.build({
+ sourcemap: true,
+ minify: false,
+ ...config,
+ });
+ }
+}
+
+main();
diff --git a/compiler/packages/react-compiler-runtime/package.json b/compiler/packages/react-compiler-runtime/package.json
index d72f168c56aad..097ab56c7a72f 100644
--- a/compiler/packages/react-compiler-runtime/package.json
+++ b/compiler/packages/react-compiler-runtime/package.json
@@ -12,8 +12,9 @@
"react": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental"
},
"scripts": {
- "build": "rimraf dist && rollup --config --bundleConfigAsCjs",
- "test": "echo 'no tests'"
+ "build": "rimraf dist && scripts/build.js",
+ "test": "echo 'no tests'",
+ "watch": "scripts/build.js --watch"
},
"repository": {
"type": "git",
diff --git a/compiler/packages/react-compiler-runtime/rollup.config.js b/compiler/packages/react-compiler-runtime/rollup.config.js
deleted file mode 100644
index 2399f2160c223..0000000000000
--- a/compiler/packages/react-compiler-runtime/rollup.config.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import typescript from '@rollup/plugin-typescript';
-import {nodeResolve} from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
-import json from '@rollup/plugin-json';
-import path from 'path';
-import process from 'process';
-import banner2 from 'rollup-plugin-banner2';
-
-const NO_INLINE = new Set(['react']);
-
-const PROD_ROLLUP_CONFIG = {
- input: 'src/index.ts',
- output: {
- file: 'dist/index.js',
- format: 'cjs',
- sourcemap: true,
- inlineDynamicImports: true,
- },
- plugins: [
- typescript({
- tsconfig: './tsconfig.json',
- compilerOptions: {
- noEmit: true,
- },
- }),
- json(),
- nodeResolve({
- preferBuiltins: true,
- resolveOnly: module => NO_INLINE.has(module) === false,
- rootDir: path.join(process.cwd(), '..'),
- }),
- commonjs(),
- banner2(
- () => `/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @lightSyntaxTransform
- * @noflow
- * @nolint
- * @preventMunge
- * @preserve-invariant-messages
- */
-
-"use no memo";` // DO NOT REMOVE
- ),
- ],
-};
-
-export default PROD_ROLLUP_CONFIG;
diff --git a/compiler/packages/react-compiler-runtime/scripts/build.js b/compiler/packages/react-compiler-runtime/scripts/build.js
new file mode 100755
index 0000000000000..c64a0fd16ed34
--- /dev/null
+++ b/compiler/packages/react-compiler-runtime/scripts/build.js
@@ -0,0 +1,67 @@
+#!/usr/bin/env node
+
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const esbuild = require('esbuild');
+const yargs = require('yargs');
+const path = require('path');
+
+const argv = yargs(process.argv.slice(2))
+ .options('p', {
+ alias: 'platform',
+ default: 'browser',
+ choices: ['browser', 'node'],
+ })
+ .options('w', {
+ alias: 'watch',
+ default: false,
+ type: 'boolean',
+ })
+ .parse();
+
+const config = {
+ entryPoints: [path.join(__dirname, '../src/index.ts')],
+ outfile: path.join(__dirname, '../dist/index.js'),
+ bundle: true,
+ external: ['react'],
+ format: argv.p === 'browser' ? 'esm' : 'cjs',
+ platform: argv.p,
+ target: 'es6',
+ banner: {
+ js: `/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @lightSyntaxTransform
+ * @noflow
+ * @nolint
+ * @preventMunge
+ * @preserve-invariant-messages
+ */
+
+"use no memo";`,
+ },
+};
+
+async function main() {
+ if (argv.w) {
+ const ctx = await esbuild.context(config);
+ await ctx.watch();
+ console.log('watching for changes...');
+ } else {
+ await esbuild.build({
+ sourcemap: true,
+ minify: false,
+ ...config,
+ });
+ }
+}
+
+main();
diff --git a/compiler/packages/react-compiler-runtime/src/index.ts b/compiler/packages/react-compiler-runtime/src/index.ts
index 57f61f3e8c017..bdaface961ed5 100644
--- a/compiler/packages/react-compiler-runtime/src/index.ts
+++ b/compiler/packages/react-compiler-runtime/src/index.ts
@@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
-'use no memo';
-
import * as React from 'react';
const {useRef, useEffect, isValidElement} = React;
diff --git a/compiler/packages/snap/package.json b/compiler/packages/snap/package.json
index e4d7b051d05a5..0fc00fab58020 100644
--- a/compiler/packages/snap/package.json
+++ b/compiler/packages/snap/package.json
@@ -10,7 +10,7 @@
],
"scripts": {
"postinstall": "./scripts/link-react-compiler-runtime.sh && perl -p -i -e 's/react\\.element/react.transitional.element/' ../../node_modules/fbt/lib/FbtReactUtil.js && perl -p -i -e 's/didWarnAboutUsingAct = false;/didWarnAboutUsingAct = true;/' ../../node_modules/react-dom/cjs/react-dom-test-utils.development.js",
- "build": "rimraf dist && concurrently -n snap,runtime \"tsc --build\" \"yarn --silent workspace react-compiler-runtime build --silent\"",
+ "build": "rimraf dist && concurrently -n snap,runtime \"tsc --build\" \"yarn --silent workspace react-compiler-runtime build -p node\"",
"test": "echo 'no tests'",
"prettier": "prettier --write 'src/**/*.ts'"
},
diff --git a/compiler/scripts/release/shared/build-packages.js b/compiler/scripts/release/shared/build-packages.js
index 9041416b778a8..4152f61271104 100644
--- a/compiler/scripts/release/shared/build-packages.js
+++ b/compiler/scripts/release/shared/build-packages.js
@@ -4,7 +4,7 @@ const {execHelper} = require('./utils');
async function buildPackages(pkgNames) {
const spinner = ora(`Building packages`).info();
for (const pkgName of pkgNames) {
- const command = `yarn workspace ${pkgName} run build`;
+ const command = `NODE_ENV=production yarn workspace ${pkgName} run build`;
spinner.start(`Running: ${command}\n`);
try {
await execHelper(command);
diff --git a/compiler/yarn.lock b/compiler/yarn.lock
index 21f771c93fd68..2723d1722013f 100644
--- a/compiler/yarn.lock
+++ b/compiler/yarn.lock
@@ -44,7 +44,7 @@
"@babel/highlight" "^7.24.7"
picocolors "^1.0.0"
-"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0":
+"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
@@ -59,9 +59,9 @@
integrity sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ==
"@babel/compat-data@^7.25.9":
- version "7.26.2"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e"
- integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.3.tgz#99488264a56b2aded63983abd6a417f03b92ed02"
+ integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==
"@babel/core@^7.0.0", "@babel/core@^7.2.0":
version "7.2.0"
@@ -115,13 +115,13 @@
source-map "^0.5.0"
trim-right "^1.0.1"
-"@babel/generator@^7.25.9", "@babel/generator@^7.26.0", "@babel/generator@^7.7.2", "@babel/generator@^7.7.4":
- version "7.26.2"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f"
- integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==
+"@babel/generator@^7.26.0", "@babel/generator@^7.26.3", "@babel/generator@^7.7.2", "@babel/generator@^7.7.4":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.3.tgz#ab8d4360544a425c90c248df7059881f4b2ce019"
+ integrity sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==
dependencies:
- "@babel/parser" "^7.26.2"
- "@babel/types" "^7.26.0"
+ "@babel/parser" "^7.26.3"
+ "@babel/types" "^7.26.3"
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^3.0.2"
@@ -675,12 +675,12 @@
dependencies:
"@babel/types" "^7.25.6"
-"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2":
- version "7.26.2"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11"
- integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==
+"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234"
+ integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==
dependencies:
- "@babel/types" "^7.26.0"
+ "@babel/types" "^7.26.3"
"@babel/parser@^7.7.4":
version "7.21.4"
@@ -1606,15 +1606,15 @@
lodash "^4.17.13"
"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.20.5", "@babel/traverse@^7.21.2", "@babel/traverse@^7.22.1", "@babel/traverse@^7.25.9":
- version "7.25.9"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
- integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
+ version "7.26.4"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd"
+ integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==
dependencies:
- "@babel/code-frame" "^7.25.9"
- "@babel/generator" "^7.25.9"
- "@babel/parser" "^7.25.9"
+ "@babel/code-frame" "^7.26.2"
+ "@babel/generator" "^7.26.3"
+ "@babel/parser" "^7.26.3"
"@babel/template" "^7.25.9"
- "@babel/types" "^7.25.9"
+ "@babel/types" "^7.26.3"
debug "^4.3.1"
globals "^11.1.0"
@@ -1680,10 +1680,10 @@
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"
-"@babel/types@^7.25.9", "@babel/types@^7.26.0":
- version "7.26.0"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff"
- integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==
+"@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0"
+ integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==
dependencies:
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
@@ -1700,6 +1700,131 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
+"@esbuild/aix-ppc64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461"
+ integrity sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==
+
+"@esbuild/android-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz#f592957ae8b5643129fa889c79e69cd8669bb894"
+ integrity sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==
+
+"@esbuild/android-arm@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz#72d8a2063aa630308af486a7e5cbcd1e134335b3"
+ integrity sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==
+
+"@esbuild/android-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz#9a7713504d5f04792f33be9c197a882b2d88febb"
+ integrity sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==
+
+"@esbuild/darwin-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz#02ae04ad8ebffd6e2ea096181b3366816b2b5936"
+ integrity sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==
+
+"@esbuild/darwin-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz#9ec312bc29c60e1b6cecadc82bd504d8adaa19e9"
+ integrity sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==
+
+"@esbuild/freebsd-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz#5e82f44cb4906d6aebf24497d6a068cfc152fa00"
+ integrity sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==
+
+"@esbuild/freebsd-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz#3fb1ce92f276168b75074b4e51aa0d8141ecce7f"
+ integrity sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==
+
+"@esbuild/linux-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz#856b632d79eb80aec0864381efd29de8fd0b1f43"
+ integrity sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==
+
+"@esbuild/linux-arm@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz#c846b4694dc5a75d1444f52257ccc5659021b736"
+ integrity sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==
+
+"@esbuild/linux-ia32@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz#f8a16615a78826ccbb6566fab9a9606cfd4a37d5"
+ integrity sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==
+
+"@esbuild/linux-loong64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz#1c451538c765bf14913512c76ed8a351e18b09fc"
+ integrity sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==
+
+"@esbuild/linux-mips64el@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz#0846edeefbc3d8d50645c51869cc64401d9239cb"
+ integrity sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==
+
+"@esbuild/linux-ppc64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz#8e3fc54505671d193337a36dfd4c1a23b8a41412"
+ integrity sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==
+
+"@esbuild/linux-riscv64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz#6a1e92096d5e68f7bb10a0d64bb5b6d1daf9a694"
+ integrity sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==
+
+"@esbuild/linux-s390x@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz#ab18e56e66f7a3c49cb97d337cd0a6fea28a8577"
+ integrity sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==
+
+"@esbuild/linux-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz#8140c9b40da634d380b0b29c837a0b4267aff38f"
+ integrity sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==
+
+"@esbuild/netbsd-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz#65f19161432bafb3981f5f20a7ff45abb2e708e6"
+ integrity sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==
+
+"@esbuild/netbsd-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz#7a3a97d77abfd11765a72f1c6f9b18f5396bcc40"
+ integrity sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==
+
+"@esbuild/openbsd-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz#58b00238dd8f123bfff68d3acc53a6ee369af89f"
+ integrity sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==
+
+"@esbuild/openbsd-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz#0ac843fda0feb85a93e288842936c21a00a8a205"
+ integrity sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==
+
+"@esbuild/sunos-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz#8b7aa895e07828d36c422a4404cc2ecf27fb15c6"
+ integrity sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==
+
+"@esbuild/win32-arm64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz#c023afb647cabf0c3ed13f0eddfc4f1d61c66a85"
+ integrity sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==
+
+"@esbuild/win32-ia32@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz#96c356132d2dda990098c8b8b951209c3cd743c2"
+ integrity sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==
+
+"@esbuild/win32-x64@0.24.2":
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz#34aa0b52d0fbb1a654b596acfa595f0c7b77a77b"
+ integrity sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==
+
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -2426,20 +2551,12 @@
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
-"@jridgewell/source-map@^0.3.3":
- version "0.3.6"
- resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a"
- integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==
- dependencies:
- "@jridgewell/gen-mapping" "^0.3.5"
- "@jridgewell/trace-mapping" "^0.3.25"
-
"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
-"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15":
+"@jridgewell/sourcemap-codec@^1.4.14":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
@@ -2512,152 +2629,6 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
-"@rollup/plugin-commonjs@^28.0.2":
- version "28.0.2"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz#193d7a86470f112b56927c1d821ee45951a819ea"
- integrity sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==
- dependencies:
- "@rollup/pluginutils" "^5.0.1"
- commondir "^1.0.1"
- estree-walker "^2.0.2"
- fdir "^6.2.0"
- is-reference "1.2.1"
- magic-string "^0.30.3"
- picomatch "^4.0.2"
-
-"@rollup/plugin-json@^6.1.0":
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.1.0.tgz#fbe784e29682e9bb6dee28ea75a1a83702e7b805"
- integrity sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==
- dependencies:
- "@rollup/pluginutils" "^5.1.0"
-
-"@rollup/plugin-node-resolve@^16.0.0":
- version "16.0.0"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.0.tgz#b1a0594661f40d7b061d82136e847354ff85f211"
- integrity sha512-0FPvAeVUT/zdWoO0jnb/V5BlBsUSNfkIOtFHzMO4H9MOklrmQFY6FduVHKucNb/aTFxvnGhj4MNj/T1oNdDfNg==
- dependencies:
- "@rollup/pluginutils" "^5.0.1"
- "@types/resolve" "1.20.2"
- deepmerge "^4.2.2"
- is-module "^1.0.0"
- resolve "^1.22.1"
-
-"@rollup/plugin-terser@^0.4.4":
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz#15dffdb3f73f121aa4fbb37e7ca6be9aeea91962"
- integrity sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==
- dependencies:
- serialize-javascript "^6.0.1"
- smob "^1.0.0"
- terser "^5.17.4"
-
-"@rollup/plugin-typescript@^12.1.2":
- version "12.1.2"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz#ebaeec2e7376faa889030ccd7cb485a649e63118"
- integrity sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==
- dependencies:
- "@rollup/pluginutils" "^5.1.0"
- resolve "^1.22.1"
-
-"@rollup/pluginutils@^5.0.1":
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.4.tgz#74f808f9053d33bafec0cc98e7b835c9667d32ba"
- integrity sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==
- dependencies:
- "@types/estree" "^1.0.0"
- estree-walker "^2.0.2"
- picomatch "^2.3.1"
-
-"@rollup/pluginutils@^5.1.0":
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0"
- integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==
- dependencies:
- "@types/estree" "^1.0.0"
- estree-walker "^2.0.2"
- picomatch "^2.3.1"
-
-"@rollup/rollup-android-arm-eabi@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5"
- integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==
-
-"@rollup/rollup-android-arm64@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb"
- integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==
-
-"@rollup/rollup-darwin-arm64@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz#6d241d099d1518ef0c2205d96b3fa52e0fe1954b"
- integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==
-
-"@rollup/rollup-darwin-x64@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791"
- integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232"
- integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==
-
-"@rollup/rollup-linux-arm-musleabihf@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa"
- integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==
-
-"@rollup/rollup-linux-arm64-gnu@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15"
- integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==
-
-"@rollup/rollup-linux-arm64-musl@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820"
- integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e"
- integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==
-
-"@rollup/rollup-linux-riscv64-gnu@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128"
- integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==
-
-"@rollup/rollup-linux-s390x-gnu@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc"
- integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==
-
-"@rollup/rollup-linux-x64-gnu@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0"
- integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==
-
-"@rollup/rollup-linux-x64-musl@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f"
- integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==
-
-"@rollup/rollup-win32-arm64-msvc@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0"
- integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==
-
-"@rollup/rollup-win32-ia32-msvc@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422"
- integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==
-
-"@rollup/rollup-win32-x64-msvc@4.22.4":
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202"
- integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==
-
"@sideway/address@^4.1.5":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5"
@@ -2822,7 +2793,7 @@
"@types/estree" "*"
"@types/json-schema" "*"
-"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0":
+"@types/estree@*":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
@@ -2926,13 +2897,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb"
integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==
-"@types/prettier@^1.0.0 || ^2.0.0 || ^3.0.0":
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-3.0.0.tgz#e9bc8160230d3a461dab5c5b41cceef1ef723057"
- integrity sha512-mFMBfMOz8QxhYVbuINtswBp9VL2b4Y0QqYHwqLz3YbgtfAcat2Dl6Y1o4e22S/OVE6Ebl9m7wWiMT2lSbAs1wA==
- dependencies:
- prettier "*"
-
"@types/prettier@^2.1.5":
version "2.7.0"
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc"
@@ -2959,11 +2923,6 @@
"@types/scheduler" "*"
csstype "^3.0.2"
-"@types/resolve@1.20.2":
- version "1.20.2"
- resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975"
- integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
-
"@types/scheduler@*":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
@@ -3213,11 +3172,6 @@ acorn@^8.4.1, acorn@^8.7.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
-acorn@^8.8.2:
- version "8.11.3"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
- integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
-
acorn@^8.9.0:
version "8.11.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
@@ -3585,13 +3539,13 @@ browserslist@^4.21.3, browserslist@^4.21.5:
update-browserslist-db "^1.0.11"
browserslist@^4.24.0:
- version "4.24.2"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580"
- integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==
+ version "4.24.3"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.3.tgz#5fc2725ca8fb3c1432e13dac278c7cc103e026d2"
+ integrity sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==
dependencies:
- caniuse-lite "^1.0.30001669"
- electron-to-chromium "^1.5.41"
- node-releases "^2.0.18"
+ caniuse-lite "^1.0.30001688"
+ electron-to-chromium "^1.5.73"
+ node-releases "^2.0.19"
update-browserslist-db "^1.1.1"
bs-logger@0.x:
@@ -3649,10 +3603,10 @@ caniuse-lite@^1.0.30001489:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz"
integrity sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==
-caniuse-lite@^1.0.30001669:
- version "1.0.30001680"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz#5380ede637a33b9f9f1fc6045ea99bd142f3da5e"
- integrity sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==
+caniuse-lite@^1.0.30001688:
+ version "1.0.30001690"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz#f2d15e3aaf8e18f76b2b8c1481abde063b8104c8"
+ integrity sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==
chalk@4, chalk@^4.0.0, chalk@^4.1.0:
version "4.1.2"
@@ -3787,11 +3741,6 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
-commander@^2.20.0:
- version "2.20.3"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
- integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -3981,11 +3930,6 @@ diff-sequences@^29.4.3:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2"
integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==
-diff@5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
- integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
-
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -4041,10 +3985,10 @@ electron-to-chromium@^1.4.411:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.418.tgz#9092aca12db25acf02a2ddf9de59f0e4363c9928"
integrity sha512-1KnpDTS9onwAfMzW50LcpNtyOkMyjd/OLoD2Kx/DDITZqgNYixY71XNszPHNxyQQ/Brh+FDcUnf4BaM041sdWg==
-electron-to-chromium@^1.5.41:
- version "1.5.63"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.63.tgz#69444d592fbbe628d129866c2355691ea93eda3e"
- integrity sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==
+electron-to-chromium@^1.5.73:
+ version "1.5.76"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz#db20295c5061b68f07c8ea4dfcbd701485d94a3d"
+ integrity sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==
emittery@^0.10.2:
version "0.10.2"
@@ -4083,6 +4027,37 @@ es5-ext@0.8.x:
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.8.2.tgz#aba8d9e1943a895ac96837a62a39b3f55ecd94ab"
integrity sha512-H19ompyhnKiBdjHR1DPHvf5RHgHPmJaY9JNzFGbMbPgdsUkvnUCN1Ke8J4Y0IMyTwFM2M9l4h2GoHwzwpSmXbA==
+esbuild@^0.24.2:
+ version "0.24.2"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.2.tgz#b5b55bee7de017bff5fb8a4e3e44f2ebe2c3567d"
+ integrity sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==
+ optionalDependencies:
+ "@esbuild/aix-ppc64" "0.24.2"
+ "@esbuild/android-arm" "0.24.2"
+ "@esbuild/android-arm64" "0.24.2"
+ "@esbuild/android-x64" "0.24.2"
+ "@esbuild/darwin-arm64" "0.24.2"
+ "@esbuild/darwin-x64" "0.24.2"
+ "@esbuild/freebsd-arm64" "0.24.2"
+ "@esbuild/freebsd-x64" "0.24.2"
+ "@esbuild/linux-arm" "0.24.2"
+ "@esbuild/linux-arm64" "0.24.2"
+ "@esbuild/linux-ia32" "0.24.2"
+ "@esbuild/linux-loong64" "0.24.2"
+ "@esbuild/linux-mips64el" "0.24.2"
+ "@esbuild/linux-ppc64" "0.24.2"
+ "@esbuild/linux-riscv64" "0.24.2"
+ "@esbuild/linux-s390x" "0.24.2"
+ "@esbuild/linux-x64" "0.24.2"
+ "@esbuild/netbsd-arm64" "0.24.2"
+ "@esbuild/netbsd-x64" "0.24.2"
+ "@esbuild/openbsd-arm64" "0.24.2"
+ "@esbuild/openbsd-x64" "0.24.2"
+ "@esbuild/sunos-x64" "0.24.2"
+ "@esbuild/win32-arm64" "0.24.2"
+ "@esbuild/win32-ia32" "0.24.2"
+ "@esbuild/win32-x64" "0.24.2"
+
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -4264,11 +4239,6 @@ estraverse@^5.1.0, estraverse@^5.2.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
-estree-walker@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
- integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
-
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@@ -4403,11 +4373,6 @@ fbt@^1.0.2:
dependencies:
invariant "^2.2.4"
-fdir@^6.2.0:
- version "6.4.2"
- resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689"
- integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==
-
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
@@ -4516,7 +4481,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-fsevents@^2.3.2, fsevents@~2.3.2:
+fsevents@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
@@ -4679,6 +4644,11 @@ hermes-estree@0.25.1:
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.25.1.tgz#6aeec17d1983b4eabf69721f3aa3eb705b17f480"
integrity sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==
+hermes-estree@0.26.0:
+ version "0.26.0"
+ resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.26.0.tgz#70da6d2e7131ec2693dac8e596e76957c4ce76ef"
+ integrity sha512-If1T7lhfXnGlVLbnsmwerNB5cyJm2oIE8TN1UKEq6/OUX1nOGUhjXMpqAwZ1wkkn9Brda0VRyJEWOGT2GgVcAQ==
+
hermes-parser@0.25.1, hermes-parser@^0.25.1:
version "0.25.1"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.25.1.tgz#5be0e487b2090886c62bd8a11724cd766d5f54d1"
@@ -4686,6 +4656,13 @@ hermes-parser@0.25.1, hermes-parser@^0.25.1:
dependencies:
hermes-estree "0.25.1"
+hermes-parser@0.26.0:
+ version "0.26.0"
+ resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.26.0.tgz#4968f8ad923a8064a65d0c1e037d754fd3a45c66"
+ integrity sha512-fWT40jJ/BtlzuyiiQS7lzNIlB5h6flVZoN8Jn8v5l987HL5dK9s+/4+py0FaBmeIEROC2zxt5qMLwXFTPLQ7BA==
+ dependencies:
+ hermes-estree "0.26.0"
+
html-encoding-sniffer@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
@@ -4834,11 +4811,6 @@ is-interactive@^1.0.0:
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
-is-module@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
- integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
-
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
@@ -4861,13 +4833,6 @@ is-potential-custom-element-name@^1.0.1:
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
-is-reference@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
- integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
- dependencies:
- "@types/estree" "*"
-
is-stream@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
@@ -6127,9 +6092,9 @@ jsesc@^2.5.1:
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
jsesc@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
- integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
+ integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==
jsesc@~0.5.0:
version "0.5.0"
@@ -6240,21 +6205,6 @@ lodash.debounce@^4.0.8:
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
-lodash.hasin@4.5.2:
- version "4.5.2"
- resolved "https://registry.yarnpkg.com/lodash.hasin/-/lodash.hasin-4.5.2.tgz#f91e352378d21ef7090b9e7687c2ca35c5b4d52a"
- integrity sha512-AFAitwTSq1Ka/1J9uBaVxpLBP5OI3INQvkl4wKcgIYxoA0S3aqO1QWXHR9aCcOrWtPFqP7GzlFncZfe0Jz0kNw==
-
-lodash.isempty@4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
- integrity sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==
-
-lodash.isnil@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/lodash.isnil/-/lodash.isnil-4.0.0.tgz#49e28cd559013458c814c5479d3c663a21bfaa6c"
- integrity sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==
-
lodash.memoize@4.x:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -6265,11 +6215,6 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-lodash.omitby@4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.omitby/-/lodash.omitby-4.6.0.tgz#5c15ff4754ad555016b53c041311e8f079204791"
- integrity sha512-5OrRcIVR75M288p4nbI2WLAf3ndw2GD9fyNv3Bc15+WCxJDdZ4lYndSxGd7hnG6PVjiJTeJE2dHEGhIuKGicIQ==
-
lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -6314,27 +6259,6 @@ lz-string@^1.4.4:
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
-magic-string@0.30.5:
- version "0.30.5"
- resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9"
- integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==
- dependencies:
- "@jridgewell/sourcemap-codec" "^1.4.15"
-
-magic-string@^0.25.7:
- version "0.25.9"
- resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
- integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==
- dependencies:
- sourcemap-codec "^1.4.8"
-
-magic-string@^0.30.3:
- version "0.30.8"
- resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613"
- integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==
- dependencies:
- "@jridgewell/sourcemap-codec" "^1.4.15"
-
make-dir@^2.0.0, make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
@@ -6477,10 +6401,10 @@ node-releases@^2.0.12:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039"
integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==
-node-releases@^2.0.18:
- version "2.0.18"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
- integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
+node-releases@^2.0.19:
+ version "2.0.19"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
+ integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
normalize-path@^3.0.0:
version "3.0.0"
@@ -6706,11 +6630,6 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-picomatch@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
- integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
-
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
@@ -6745,16 +6664,16 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
-prettier-plugin-hermes-parser@0.25.1, prettier-plugin-hermes-parser@^0.25.1:
- version "0.25.1"
- resolved "https://registry.yarnpkg.com/prettier-plugin-hermes-parser/-/prettier-plugin-hermes-parser-0.25.1.tgz#f7e82357f7fdcf5fcdf9e06dcc3bbafe03ed61eb"
- integrity sha512-qVsgSt1ZLz7sxQyMmLM3b8JYIcUt4pkE+OCMEoUTe5G87ghNe9lluYMy7ptu1h0f3fAZ+zkifUV3JojMmQcKkg==
+prettier-plugin-hermes-parser@0.26.0, prettier-plugin-hermes-parser@^0.26.0:
+ version "0.26.0"
+ resolved "https://registry.yarnpkg.com/prettier-plugin-hermes-parser/-/prettier-plugin-hermes-parser-0.26.0.tgz#f097ef381c99f624ae491b68ed0e5719b2249caa"
+ integrity sha512-ajjlx/0OQ+lcZQEnKEUDU7Srr9vw1OoMO6qZDIYmck1u7j9STiCStqb3RG1vE7FripXYAhquuI+oYG8BCTNC4g==
dependencies:
- hermes-estree "0.25.1"
- hermes-parser "0.25.1"
- prettier-plugin-hermes-parser "0.25.1"
+ hermes-estree "0.26.0"
+ hermes-parser "0.26.0"
+ prettier-plugin-hermes-parser "0.26.0"
-prettier@*, prettier@^3.3.3:
+prettier@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105"
integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
@@ -6857,13 +6776,6 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
-randombytes@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
- integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
- dependencies:
- safe-buffer "^5.1.0"
-
react-dom@0.0.0-experimental-4beb1fd8-20241118:
version "0.0.0-experimental-4beb1fd8-20241118"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-4beb1fd8-20241118.tgz#bf51483d52faea0618abef7d7eab681eea328ac7"
@@ -7000,7 +6912,7 @@ resolve.exports@^2.0.0:
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-resolve@^1.14.2, resolve@^1.22.1:
+resolve@^1.14.2:
version "1.22.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
@@ -7038,51 +6950,6 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-rollup-plugin-banner2@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/rollup-plugin-banner2/-/rollup-plugin-banner2-1.2.3.tgz#4aa454e41a80623180164625368ec0321641a0ef"
- integrity sha512-lhpPoDTRZMIvSK1AppGNDIZ4fnQuW4WuENuswSUzvXhTR596zWNOmCaCYoqD15QixnjnG+wT+jauLEK5qGRPZg==
- dependencies:
- magic-string "^0.25.7"
-
-rollup-plugin-prettier@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/rollup-plugin-prettier/-/rollup-plugin-prettier-4.1.1.tgz#eb74bd47c3cc3ba68bdf34b5323d0d7a47be8cec"
- integrity sha512-ugpi/EqW12yJa4NO3o4f/wt/YHwiQovVGC2jxZgxuKO9osjt4lVxVA427+itl87XmQc6089ZkpDc6OpaOZKWgQ==
- dependencies:
- "@types/prettier" "^1.0.0 || ^2.0.0 || ^3.0.0"
- diff "5.1.0"
- lodash.hasin "4.5.2"
- lodash.isempty "4.4.0"
- lodash.isnil "4.0.0"
- lodash.omitby "4.6.0"
- magic-string "0.30.5"
-
-rollup@^4.22.4:
- version "4.22.4"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.4.tgz#4135a6446671cd2a2453e1ad42a45d5973ec3a0f"
- integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==
- dependencies:
- "@types/estree" "1.0.5"
- optionalDependencies:
- "@rollup/rollup-android-arm-eabi" "4.22.4"
- "@rollup/rollup-android-arm64" "4.22.4"
- "@rollup/rollup-darwin-arm64" "4.22.4"
- "@rollup/rollup-darwin-x64" "4.22.4"
- "@rollup/rollup-linux-arm-gnueabihf" "4.22.4"
- "@rollup/rollup-linux-arm-musleabihf" "4.22.4"
- "@rollup/rollup-linux-arm64-gnu" "4.22.4"
- "@rollup/rollup-linux-arm64-musl" "4.22.4"
- "@rollup/rollup-linux-powerpc64le-gnu" "4.22.4"
- "@rollup/rollup-linux-riscv64-gnu" "4.22.4"
- "@rollup/rollup-linux-s390x-gnu" "4.22.4"
- "@rollup/rollup-linux-x64-gnu" "4.22.4"
- "@rollup/rollup-linux-x64-musl" "4.22.4"
- "@rollup/rollup-win32-arm64-msvc" "4.22.4"
- "@rollup/rollup-win32-ia32-msvc" "4.22.4"
- "@rollup/rollup-win32-x64-msvc" "4.22.4"
- fsevents "~2.3.2"
-
rrweb-cssom@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1"
@@ -7102,16 +6969,16 @@ rxjs@^7.0.0, rxjs@^7.8.1:
dependencies:
tslib "^2.1.0"
-safe-buffer@^5.1.0, safe-buffer@~5.2.0:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
- integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+safe-buffer@~5.2.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
"safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -7163,13 +7030,6 @@ semver@^7.6.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
-serialize-javascript@^6.0.1:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2"
- integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
- dependencies:
- randombytes "^2.1.0"
-
set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@@ -7219,11 +7079,6 @@ slash@^3.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-smob@^1.0.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab"
- integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==
-
source-map-support@0.5.13:
version "0.5.13"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
@@ -7232,7 +7087,7 @@ source-map-support@0.5.13:
buffer-from "^1.0.0"
source-map "^0.6.0"
-source-map-support@^0.5.16, source-map-support@~0.5.20:
+source-map-support@^0.5.16:
version "0.5.21"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
@@ -7250,11 +7105,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-sourcemap-codec@^1.4.8:
- version "1.4.8"
- resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
- integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
-
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
@@ -7397,16 +7247,6 @@ terminal-link@^2.0.0:
ansi-escapes "^4.2.1"
supports-hyperlinks "^2.0.0"
-terser@^5.17.4:
- version "5.30.2"
- resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.2.tgz#79fc2222c241647cea54ab928ac987ffbe8ce9e2"
- integrity sha512-vTDjRKYKip4dOFL5VizdoxHTYDfEXPdz5t+FbxCC5Rp2s+KbEO8w5wqMDPgj7CtFKZuzq7PXv28fZoXfqqBVuw==
- dependencies:
- "@jridgewell/source-map" "^0.3.3"
- acorn "^8.8.2"
- commander "^2.20.0"
- source-map-support "~0.5.20"
-
test-exclude@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
diff --git a/packages/react-dom/src/__tests__/CSSPropertyOperations-test.js b/packages/react-dom/src/__tests__/CSSPropertyOperations-test.js
index bda95b8434d46..b5671cf759cef 100644
--- a/packages/react-dom/src/__tests__/CSSPropertyOperations-test.js
+++ b/packages/react-dom/src/__tests__/CSSPropertyOperations-test.js
@@ -13,6 +13,8 @@ const React = require('react');
const ReactDOMClient = require('react-dom/client');
const ReactDOMServer = require('react-dom/server');
const act = require('internal-test-utils').act;
+const assertConsoleErrorDev =
+ require('internal-test-utils').assertConsoleErrorDev;
describe('CSSPropertyOperations', () => {
it('should automatically append `px` to relevant styles', () => {
@@ -103,15 +105,14 @@ describe('CSSPropertyOperations', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Unsupported style property background-color. Did you mean backgroundColor?' +
'\n in div (at **)' +
'\n in Comp (at **)',
- );
+ ]);
});
it('should warn when updating hyphenated style names', async () => {
@@ -132,11 +133,10 @@ describe('CSSPropertyOperations', () => {
await act(() => {
root.render();
});
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Unsupported style property -ms-transform. Did you mean msTransform?' +
'\n in div (at **)' +
'\n in Comp (at **)',
@@ -165,11 +165,10 @@ describe('CSSPropertyOperations', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
// msTransform is correct already and shouldn't warn
'Unsupported vendor-prefixed style property oTransform. ' +
'Did you mean OTransform?' +
@@ -202,11 +201,10 @@ describe('CSSPropertyOperations', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
"Style property values shouldn't contain a semicolon. " +
'Try "backgroundColor: blue" instead.' +
'\n in div (at **)' +
@@ -229,15 +227,14 @@ describe('CSSPropertyOperations', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'`NaN` is an invalid value for the `fontSize` css style property.' +
'\n in div (at **)' +
'\n in Comp (at **)',
- );
+ ]);
});
it('should not warn when setting CSS custom properties', async () => {
@@ -265,15 +262,14 @@ describe('CSSPropertyOperations', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'`Infinity` is an invalid value for the `fontSize` css style property.' +
'\n in div (at **)' +
'\n in Comp (at **)',
- );
+ ]);
});
it('should not add units to CSS custom properties', async () => {
diff --git a/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js b/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js
index cecc71b45a6c0..ef09e49bf36c1 100644
--- a/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js
+++ b/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js
@@ -1333,7 +1333,8 @@ describe('DOMPropertyOperations', () => {
});
assertConsoleErrorDev([
- 'The `popoverTarget` prop expects the ID of an Element as a string. Received HTMLDivElement {} instead.',
+ 'The `popoverTarget` prop expects the ID of an Element as a string. Received HTMLDivElement {} instead.\n' +
+ ' in button (at **)',
]);
// Dedupe warning
@@ -1375,13 +1376,17 @@ describe('DOMPropertyOperations', () => {
expect(container.firstChild.getAttribute('value')).toBe('foo');
}
expect(container.firstChild.value).toBe('foo');
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'A component is changing a controlled input to be uncontrolled',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'A component is changing a controlled input to be uncontrolled. ' +
+ 'This is likely caused by the value changing from a defined to undefined, ' +
+ 'which should not happen. Decide between using a controlled or uncontrolled ' +
+ 'input element for the lifetime of the component. ' +
+ 'More info: https://react.dev/link/controlled-components\n' +
+ ' in input (at **)',
+ ]);
if (disableInputAttributeSyncing) {
expect(container.firstChild.hasAttribute('value')).toBe(false);
} else {
diff --git a/packages/react-dom/src/__tests__/InvalidEventListeners-test.js b/packages/react-dom/src/__tests__/InvalidEventListeners-test.js
index d7045d2756ad4..8bff125c82c32 100644
--- a/packages/react-dom/src/__tests__/InvalidEventListeners-test.js
+++ b/packages/react-dom/src/__tests__/InvalidEventListeners-test.js
@@ -15,13 +15,14 @@ describe('InvalidEventListeners', () => {
let React;
let ReactDOMClient;
let act;
+ let assertConsoleErrorDev;
let container;
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactDOMClient = require('react-dom/client');
- act = require('internal-test-utils').act;
+ ({act, assertConsoleErrorDev} = require('internal-test-utils'));
container = document.createElement('div');
document.body.appendChild(container);
@@ -34,13 +35,13 @@ describe('InvalidEventListeners', () => {
it('should prevent non-function listeners, at dispatch', async () => {
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(
);
- });
- }).toErrorDev(
- 'Expected `onClick` listener to be a function, instead got a value of `string` type.',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Expected `onClick` listener to be a function, instead got a value of `string` type.\n' +
+ ' in div (at **)',
+ ]);
const node = container.firstChild;
console.error = jest.fn();
diff --git a/packages/react-dom/src/__tests__/ReactChildReconciler-test.js b/packages/react-dom/src/__tests__/ReactChildReconciler-test.js
index 1c1475534f3e0..ba0c028fa863a 100644
--- a/packages/react-dom/src/__tests__/ReactChildReconciler-test.js
+++ b/packages/react-dom/src/__tests__/ReactChildReconciler-test.js
@@ -15,6 +15,7 @@
let React;
let ReactDOMClient;
let act;
+let assertConsoleErrorDev;
describe('ReactChildReconciler', () => {
beforeEach(() => {
@@ -22,7 +23,7 @@ describe('ReactChildReconciler', () => {
React = require('react');
ReactDOMClient = require('react-dom/client');
- act = require('internal-test-utils').act;
+ ({act, assertConsoleErrorDev} = require('internal-test-utils'));
});
function createIterable(array) {
@@ -62,15 +63,21 @@ describe('ReactChildReconciler', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(
-
-
{iterableFunction}
-
,
- );
- });
- }).toErrorDev('Functions are not valid as a React child');
+ await act(() => {
+ root.render(
+
+
{iterableFunction}
+
,
+ );
+ });
+ assertConsoleErrorDev([
+ 'Functions are not valid as a React child. ' +
+ 'This may happen if you return fn instead of from render. ' +
+ 'Or maybe you meant to call this function rather than return it.\n' +
+ '
{fn}
\n' +
+ ' in h1 (at **)' +
+ (gate('enableOwnerStacks') ? '' : '\n in div (at **)'),
+ ]);
const node = container.firstChild;
expect(node.innerHTML).toContain(''); // h1
@@ -85,16 +92,18 @@ describe('ReactChildReconciler', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Keys should be unique so that components maintain their identity ' +
- 'across updates. Non-unique keys may cause children to be ' +
- 'duplicated and/or omitted — the behavior is unsupported and ' +
- 'could change in a future version.',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Encountered two children with the same key, `1`. ' +
+ 'Keys should be unique so that components maintain their identity across updates. ' +
+ 'Non-unique keys may cause children to be duplicated and/or omitted — ' +
+ 'the behavior is unsupported and could change in a future version.\n' +
+ (gate('enableOwnerStacks') ? '' : ' in div (at **)\n') +
+ ' in div (at **)\n' +
+ ' in Component (at **)',
+ ]);
});
it('warns for duplicated array keys with component stack info', async () => {
@@ -118,11 +127,10 @@ describe('ReactChildReconciler', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Encountered two children with the same key, `1`. ' +
'Keys should be unique so that components maintain their identity ' +
'across updates. Non-unique keys may cause children to be ' +
@@ -135,7 +143,7 @@ describe('ReactChildReconciler', () => {
? ''
: ' in Parent (at **)\n') +
' in GrandParent (at **)',
- );
+ ]);
});
it('warns for duplicated iterable keys', async () => {
@@ -147,16 +155,19 @@ describe('ReactChildReconciler', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Keys should be unique so that components maintain their identity ' +
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Encountered two children with the same key, `1`. ' +
+ 'Keys should be unique so that components maintain their identity ' +
'across updates. Non-unique keys may cause children to be ' +
'duplicated and/or omitted — the behavior is unsupported and ' +
- 'could change in a future version.',
- );
+ 'could change in a future version.\n' +
+ ' in div (at **)\n' +
+ (gate(flags => flags.enableOwnerStacks) ? '' : ' in div (at **)\n') +
+ ' in Component (at **)',
+ ]);
});
it('warns for duplicated iterable keys with component stack info', async () => {
@@ -180,11 +191,10 @@ describe('ReactChildReconciler', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Encountered two children with the same key, `1`. ' +
'Keys should be unique so that components maintain their identity ' +
'across updates. Non-unique keys may cause children to be ' +
@@ -197,6 +207,6 @@ describe('ReactChildReconciler', () => {
? ''
: ' in Parent (at **)\n') +
' in GrandParent (at **)',
- );
+ ]);
});
});
diff --git a/packages/react-dom/src/__tests__/ReactComponent-test.js b/packages/react-dom/src/__tests__/ReactComponent-test.js
index 6459114697540..c59ba61e01c44 100644
--- a/packages/react-dom/src/__tests__/ReactComponent-test.js
+++ b/packages/react-dom/src/__tests__/ReactComponent-test.js
@@ -411,7 +411,9 @@ describe('ReactComponent', () => {
assertConsoleErrorDev(
[
'React.jsx: type is invalid -- expected a string (for built-in components) ' +
- 'or a class/function (for composite components) but got: undefined.',
+ 'or a class/function (for composite components) but got: undefined. ' +
+ "You likely forgot to export your component from the file it's defined in, " +
+ 'or you might have mixed up default and named imports.',
],
{withoutStack: true},
);
@@ -491,16 +493,11 @@ describe('ReactComponent', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(
- expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'React.jsx: type is invalid -- expected a string (for built-in components) ' +
- 'or a class/function (for composite components) but got: undefined.',
- ),
- ).rejects.toThrowError(
+ await expect(async () => {
+ await act(() => {
+ root.render();
+ });
+ }).rejects.toThrowError(
'Element type is invalid: expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: undefined.' +
(__DEV__
@@ -509,6 +506,26 @@ describe('ReactComponent', () => {
'\n\nCheck the render method of `Bar`.'
: ''),
);
+ if (!gate('enableOwnerStacks')) {
+ assertConsoleErrorDev([
+ 'React.jsx: type is invalid -- expected a string (for built-in components) ' +
+ 'or a class/function (for composite components) but got: undefined.' +
+ (__DEV__
+ ? " You likely forgot to export your component from the file it's defined in, " +
+ 'or you might have mixed up default and named imports.\n' +
+ ' in Bar (at **)\n' +
+ ' in Foo (at **)'
+ : ''),
+ 'React.jsx: type is invalid -- expected a string (for built-in components) ' +
+ 'or a class/function (for composite components) but got: undefined.' +
+ (__DEV__
+ ? " You likely forgot to export your component from the file it's defined in, " +
+ 'or you might have mixed up default and named imports.\n' +
+ ' in Bar (at **)\n' +
+ ' in Foo (at **)'
+ : ''),
+ ]);
+ }
});
it('throws if a plain object is used as a child', async () => {
@@ -624,17 +641,16 @@ describe('ReactComponent', () => {
}
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Functions are not valid as a React child. This may happen if ' +
'you return Foo instead of from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' {Foo}\n' +
' in Foo (at **)',
- );
+ ]);
});
it('warns on function as a return value from a class', async () => {
@@ -644,19 +660,18 @@ describe('ReactComponent', () => {
}
}
const container = document.createElement('div');
- await expect(async () => {
- const root = ReactDOMClient.createRoot(container);
+ const root = ReactDOMClient.createRoot(container);
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Functions are not valid as a React child. This may happen if ' +
'you return Foo instead of from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' {Foo}\n' +
' in Foo (at **)',
- );
+ ]);
});
it('warns on function as a child to host component', async () => {
@@ -669,11 +684,10 @@ describe('ReactComponent', () => {
}
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Functions are not valid as a React child. This may happen if ' +
'you return Foo instead of from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
@@ -683,7 +697,7 @@ describe('ReactComponent', () => {
? ''
: ' in div (at **)\n') +
' in Foo (at **)',
- );
+ ]);
});
it('does not warn for function-as-a-child that gets resolved', async () => {
@@ -724,11 +738,10 @@ describe('ReactComponent', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
let component;
- await expect(async () => {
- await act(() => {
- root.render( (component = current)} />);
- });
- }).toErrorDev([
+ await act(() => {
+ root.render( (component = current)} />);
+ });
+ assertConsoleErrorDev([
'Functions are not valid as a React child. This may happen if ' +
'you return Foo instead of from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
diff --git a/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js b/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
index 428dac1f1ea9e..75e4cebe80610 100644
--- a/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+++ b/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
@@ -14,6 +14,8 @@ let act;
let React;
let ReactDOM;
let ReactDOMClient;
+let assertConsoleErrorDev;
+let assertConsoleWarnDev;
const clone = function (o) {
return JSON.parse(JSON.stringify(o));
@@ -90,7 +92,11 @@ describe('ReactComponentLifeCycle', () => {
beforeEach(() => {
jest.resetModules();
- act = require('internal-test-utils').act;
+ ({
+ act,
+ assertConsoleErrorDev,
+ assertConsoleWarnDev,
+ } = require('internal-test-utils'));
React = require('react');
ReactDOM = require('react-dom');
@@ -239,15 +245,15 @@ describe('ReactComponentLifeCycle', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'StatefulComponent: It is not recommended to assign props directly to state ' +
"because updates to props won't be reflected in state. " +
- 'In most cases, it is better to use props directly.',
- );
+ 'In most cases, it is better to use props directly.\n' +
+ ' in StatefulComponent (at **)',
+ ]);
});
it('should not allow update state inside of getInitialState', async () => {
@@ -266,16 +272,16 @@ describe('ReactComponentLifeCycle', () => {
let container = document.createElement('div');
let root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
"Can't call setState on a component that is not yet mounted. " +
'This is a no-op, but it might indicate a bug in your application. ' +
'Instead, assign to `this.state` directly or define a `state = {};` ' +
- 'class property with the desired state in the StatefulComponent component.',
- );
+ 'class property with the desired state in the StatefulComponent component.\n' +
+ ' in StatefulComponent (at **)',
+ ]);
container = document.createElement('div');
root = ReactDOMClient.createRoot(container);
@@ -308,11 +314,17 @@ describe('ReactComponentLifeCycle', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(element);
- });
- }).toErrorDev('Component is accessing isMounted inside its render()');
+ await act(() => {
+ root.render(element);
+ });
+ assertConsoleErrorDev([
+ 'Component is accessing isMounted inside its render() function. ' +
+ 'render() should be a pure function of props and state. ' +
+ 'It should never access something that requires stale data ' +
+ 'from the previous render, such as refs. ' +
+ 'Move this logic to componentDidMount and componentDidUpdate instead.\n' +
+ ' in Component (at **)',
+ ]);
expect(instance._isMounted()).toBeTruthy();
});
@@ -340,11 +352,17 @@ describe('ReactComponentLifeCycle', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(element);
- });
- }).toErrorDev('Component is accessing isMounted inside its render()');
+ await act(() => {
+ root.render(element);
+ });
+ assertConsoleErrorDev([
+ 'Component is accessing isMounted inside its render() function. ' +
+ 'render() should be a pure function of props and state. ' +
+ 'It should never access something that requires stale data ' +
+ 'from the previous render, such as refs. ' +
+ 'Move this logic to componentDidMount and componentDidUpdate instead.\n' +
+ ' in Component (at **)',
+ ]);
expect(instance._isMounted()).toBeTruthy();
});
@@ -390,11 +408,17 @@ describe('ReactComponentLifeCycle', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev('Component is accessing findDOMNode inside its render()');
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Component is accessing findDOMNode inside its render(). ' +
+ 'render() should be a pure function of props and state. ' +
+ 'It should never access something that requires stale data ' +
+ 'from the previous render, such as refs. ' +
+ 'Move this logic to componentDidMount and componentDidUpdate instead.\n' +
+ ' in Component (at **)',
+ ]);
});
it('should carry through each of the phases of setup', async () => {
@@ -453,13 +477,17 @@ describe('ReactComponentLifeCycle', () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
const instanceRef = React.createRef();
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'LifeCycleComponent is accessing isMounted inside its render() function',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'LifeCycleComponent is accessing isMounted inside its render() function. ' +
+ 'render() should be a pure function of props and state. ' +
+ 'It should never access something that requires stale data ' +
+ 'from the previous render, such as refs. ' +
+ 'Move this logic to componentDidMount and componentDidUpdate instead.\n' +
+ ' in LifeCycleComponent (at **)',
+ ]);
const instance = instanceRef.current;
// getInitialState
@@ -781,19 +809,45 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.',
- );
- }).toWarnDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'Component uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
+ ' componentWillMount\n' +
+ ' componentWillReceiveProps\n' +
+ ' componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in Component (at **)',
+ ]);
+ assertConsoleWarnDev(
[
- 'componentWillMount has been renamed',
- 'componentWillReceiveProps has been renamed',
- 'componentWillUpdate has been renamed',
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: Component',
+ 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ "* If you're updating state whenever props change, refactor your code to use " +
+ 'memoization techniques or move it to static getDerivedStateFromProps. ' +
+ 'Learn more at: https://react.dev/link/derived-state\n' +
+ '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: Component',
+ 'componentWillUpdate has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: Component',
],
{withoutStack: true},
);
@@ -821,20 +875,45 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await expect(
- async () =>
- await act(() => {
- root.render();
- }),
- ).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.',
- );
- }).toWarnDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'Component uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
+ ' componentWillMount\n' +
+ ' componentWillReceiveProps\n' +
+ ' componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in Component (at **)',
+ ]);
+ assertConsoleWarnDev(
[
- 'componentWillMount has been renamed',
- 'componentWillReceiveProps has been renamed',
- 'componentWillUpdate has been renamed',
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: Component',
+ 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ "* If you're updating state whenever props change, refactor your code to use " +
+ 'memoization techniques or move it to static getDerivedStateFromProps. ' +
+ 'Learn more at: https://react.dev/link/derived-state\n' +
+ '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: Component',
+ 'componentWillUpdate has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: Component',
],
{withoutStack: true},
);
@@ -865,14 +944,19 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(
- async () =>
- await act(() => {
- root.render();
- }),
- ).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'Component uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
+ ' UNSAFE_componentWillMount\n' +
+ ' UNSAFE_componentWillReceiveProps\n' +
+ ' UNSAFE_componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in Component (at **)',
+ ]);
await act(() => {
root.render();
});
@@ -893,24 +977,35 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
- 'AllLegacyLifecycles uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
- ' componentWillMount\n' +
- ' UNSAFE_componentWillReceiveProps\n' +
- ' componentWillUpdate\n\n' +
- 'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
- }).toWarnDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'AllLegacyLifecycles uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
+ ' componentWillMount\n' +
+ ' UNSAFE_componentWillReceiveProps\n' +
+ ' componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in AllLegacyLifecycles (at **)',
+ ]);
+ assertConsoleWarnDev(
[
- 'componentWillMount has been renamed',
- 'componentWillUpdate has been renamed',
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: AllLegacyLifecycles',
+ 'componentWillUpdate has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: AllLegacyLifecycles',
],
{withoutStack: true},
);
@@ -926,17 +1021,17 @@ describe('ReactComponentLifeCycle', () => {
}
}
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
'WillMount uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
' UNSAFE_componentWillMount\n\n' +
'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in WillMount (at **)',
+ ]);
class WillMountAndUpdate extends React.Component {
state = {};
@@ -950,23 +1045,30 @@ describe('ReactComponentLifeCycle', () => {
}
}
- await expect(async () => {
- await expect(
- async () =>
- await act(() => {
- root.render();
- }),
- ).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
- 'WillMountAndUpdate uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
- ' componentWillMount\n' +
- ' UNSAFE_componentWillUpdate\n\n' +
- 'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
- }).toWarnDev(['componentWillMount has been renamed'], {
- withoutStack: true,
+ await act(() => {
+ root.render();
});
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'WillMountAndUpdate uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
+ ' componentWillMount\n' +
+ ' UNSAFE_componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in WillMountAndUpdate (at **)',
+ ]);
+ assertConsoleWarnDev(
+ [
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: WillMountAndUpdate',
+ ],
+ {withoutStack: true},
+ );
class WillReceiveProps extends React.Component {
state = {};
@@ -979,21 +1081,34 @@ describe('ReactComponentLifeCycle', () => {
}
}
- await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
- 'WillReceiveProps uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
- ' componentWillReceiveProps\n\n' +
- 'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
- }).toWarnDev(['componentWillReceiveProps has been renamed'], {
- withoutStack: true,
+ await act(() => {
+ root.render();
});
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'WillReceiveProps uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
+ ' componentWillReceiveProps\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in WillReceiveProps (at **)',
+ ]);
+ assertConsoleWarnDev(
+ [
+ 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ "* If you're updating state whenever props change, refactor your code to use " +
+ 'memoization techniques or move it to static getDerivedStateFromProps. ' +
+ 'Learn more at: https://react.dev/link/derived-state\n' +
+ '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: WillReceiveProps',
+ ],
+ {
+ withoutStack: true,
+ },
+ );
});
it('should warn about deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', async () => {
@@ -1010,24 +1125,35 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
- 'AllLegacyLifecycles uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
- ' componentWillMount\n' +
- ' UNSAFE_componentWillReceiveProps\n' +
- ' componentWillUpdate\n\n' +
- 'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
- }).toWarnDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'AllLegacyLifecycles uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
+ ' componentWillMount\n' +
+ ' UNSAFE_componentWillReceiveProps\n' +
+ ' componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in AllLegacyLifecycles (at **)',
+ ]);
+ assertConsoleWarnDev(
[
- 'componentWillMount has been renamed',
- 'componentWillUpdate has been renamed',
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: AllLegacyLifecycles',
+ 'componentWillUpdate has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: AllLegacyLifecycles',
],
{withoutStack: true},
);
@@ -1042,17 +1168,17 @@ describe('ReactComponentLifeCycle', () => {
}
}
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
'WillMount uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
' UNSAFE_componentWillMount\n\n' +
'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in WillMount (at **)',
+ ]);
class WillMountAndUpdate extends React.Component {
state = {};
@@ -1065,22 +1191,32 @@ describe('ReactComponentLifeCycle', () => {
}
}
- await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
- 'WillMountAndUpdate uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
- ' componentWillMount\n' +
- ' UNSAFE_componentWillUpdate\n\n' +
- 'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
- }).toWarnDev(['componentWillMount has been renamed'], {
- withoutStack: true,
+ await act(() => {
+ root.render();
});
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'WillMountAndUpdate uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
+ ' componentWillMount\n' +
+ ' UNSAFE_componentWillUpdate\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in WillMountAndUpdate (at **)',
+ ]);
+ assertConsoleWarnDev(
+ [
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: WillMountAndUpdate',
+ ],
+ {
+ withoutStack: true,
+ },
+ );
class WillReceiveProps extends React.Component {
state = {};
@@ -1092,22 +1228,34 @@ describe('ReactComponentLifeCycle', () => {
}
}
- await expect(async () => {
- await expect(
- async () =>
- await act(() => {
- root.render();
- }),
- ).toErrorDev(
- 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
- 'WillReceiveProps uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
- ' componentWillReceiveProps\n\n' +
- 'The above lifecycles should be removed. Learn more about this warning here:\n' +
- 'https://react.dev/link/unsafe-component-lifecycles',
- );
- }).toWarnDev(['componentWillReceiveProps has been renamed'], {
- withoutStack: true,
+ await act(() => {
+ root.render();
});
+ assertConsoleErrorDev([
+ 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
+ 'WillReceiveProps uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
+ ' componentWillReceiveProps\n\n' +
+ 'The above lifecycles should be removed. Learn more about this warning here:\n' +
+ 'https://react.dev/link/unsafe-component-lifecycles\n' +
+ ' in WillReceiveProps (at **)',
+ ]);
+ assertConsoleWarnDev(
+ [
+ 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ "* If you're updating state whenever props change, refactor your code to use " +
+ 'memoization techniques or move it to static getDerivedStateFromProps. ' +
+ 'Learn more at: https://react.dev/link/derived-state\n' +
+ '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: WillReceiveProps',
+ ],
+ {
+ withoutStack: true,
+ },
+ );
});
it('should warn if getDerivedStateFromProps returns undefined', async () => {
@@ -1120,14 +1268,14 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'MyComponent.getDerivedStateFromProps(): A valid state object (or null) must ' +
- 'be returned. You have returned undefined.',
- );
+ 'be returned. You have returned undefined.\n' +
+ ' in MyComponent (at **)',
+ ]);
// De-duped
await act(() => {
@@ -1146,16 +1294,16 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'`MyComponent` uses `getDerivedStateFromProps` but its initial state is ' +
'undefined. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `MyComponent`. ' +
- 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
- );
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.\n' +
+ ' in MyComponent (at **)',
+ ]);
// De-duped
await act(() => {
@@ -1191,15 +1339,35 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toWarnDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleWarnDev(
[
- 'componentWillMount has been renamed',
- 'componentWillReceiveProps has been renamed',
- 'componentWillUpdate has been renamed',
+ 'componentWillMount has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
+ '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: MyComponent',
+ 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ "* If you're updating state whenever props change, refactor your code to use " +
+ 'memoization techniques or move it to static getDerivedStateFromProps. ' +
+ 'Learn more at: https://react.dev/link/derived-state\n' +
+ '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: MyComponent',
+ 'componentWillUpdate has been renamed, and is not recommended for use. ' +
+ 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
+ '* Move data fetching code or side effects to componentDidUpdate.\n' +
+ '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
+ 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
+ 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
+ 'Please update the following components: MyComponent',
],
{withoutStack: true},
);
@@ -1444,14 +1612,14 @@ describe('ReactComponentLifeCycle', () => {
root.render();
});
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'MyComponent.getSnapshotBeforeUpdate(): A snapshot value (or null) must ' +
- 'be returned. You have returned undefined.',
- );
+ 'be returned. You have returned undefined.\n' +
+ ' in MyComponent (at **)',
+ ]);
// De-duped
await act(() => {
@@ -1470,14 +1638,14 @@ describe('ReactComponentLifeCycle', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'MyComponent: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' +
- 'This component defines getSnapshotBeforeUpdate() only.',
- );
+ 'This component defines getSnapshotBeforeUpdate() only.\n' +
+ ' in MyComponent (at **)',
+ ]);
// De-duped
await act(() => {
@@ -1497,11 +1665,10 @@ describe('ReactComponentLifeCycle', () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toWarnDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleWarnDev(
[
`componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
diff --git a/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js b/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
index 30b5ced5cf2e3..3d5f61c1ed520 100644
--- a/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
+++ b/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
@@ -18,6 +18,7 @@ let ReactSharedInternals;
let Scheduler;
let assertLog;
let act;
+let assertConsoleErrorDev;
describe('ReactCompositeComponent', () => {
const hasOwnProperty = Object.prototype.hasOwnProperty;
@@ -71,7 +72,7 @@ describe('ReactCompositeComponent', () => {
require('react').__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
Scheduler = require('scheduler');
assertLog = require('internal-test-utils').assertLog;
- act = require('internal-test-utils').act;
+ ({act, assertConsoleErrorDev} = require('internal-test-utils'));
});
describe('MorphingComponent', () => {
@@ -308,16 +309,16 @@ describe('ReactCompositeComponent', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
"Can't call forceUpdate on a component that is not yet mounted. " +
'This is a no-op, but it might indicate a bug in your application. ' +
'Instead, assign to `this.state` directly or define a `state = {};` ' +
- 'class property with the desired state in the MyComponent component.',
- );
+ 'class property with the desired state in the MyComponent component.\n' +
+ ' in MyComponent (at **)',
+ ]);
// No additional warning should be recorded
const container2 = document.createElement('div');
@@ -342,16 +343,16 @@ describe('ReactCompositeComponent', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
"Can't call setState on a component that is not yet mounted. " +
'This is a no-op, but it might indicate a bug in your application. ' +
'Instead, assign to `this.state` directly or define a `state = {};` ' +
- 'class property with the desired state in the MyComponent component.',
- );
+ 'class property with the desired state in the MyComponent component.\n' +
+ ' in MyComponent (at **)',
+ ]);
// No additional warning should be recorded
const container2 = document.createElement('div');
@@ -478,16 +479,16 @@ describe('ReactCompositeComponent', () => {
}
const root = ReactDOMClient.createRoot(container);
await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).rejects.toThrow(TypeError);
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ }).rejects.toThrow(TypeError);
+ assertConsoleErrorDev([
'The component appears to have a render method, ' +
"but doesn't extend React.Component. This is likely to cause errors. " +
- 'Change ClassWithRenderNotExtended to extend React.Component instead.',
- );
+ 'Change ClassWithRenderNotExtended to extend React.Component instead.\n' +
+ ' in ClassWithRenderNotExtended (at **)',
+ ]);
// Test deduplication
await expect(async () => {
@@ -514,14 +515,14 @@ describe('ReactCompositeComponent', () => {
let instance;
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render( (instance = ref)} />);
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render( (instance = ref)} />);
+ });
+ assertConsoleErrorDev([
'Cannot update during an existing state transition (such as within ' +
- '`render`). Render methods should be a pure function of props and state.',
- );
+ '`render`). Render methods should be a pure function of props and state.\n' +
+ ' in Component (at **)',
+ ]);
// The setState call is queued and then executed as a second pass. This
// behavior is undefined though so we're free to change it to suit the
@@ -618,14 +619,14 @@ describe('ReactCompositeComponent', () => {
root.render( (instance = ref)} />);
});
- expect(() => {
- ReactDOM.flushSync(() => {
- instance.setState({bogus: true});
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ instance.setState({bogus: true});
+ });
+ assertConsoleErrorDev([
'ClassComponent.shouldComponentUpdate(): Returned undefined instead of a ' +
- 'boolean value. Make sure to return true or false.',
- );
+ 'boolean value. Make sure to return true or false.\n' +
+ ' in ClassComponent (at **)',
+ ]);
});
it('should warn when componentDidUnmount method is defined', async () => {
@@ -638,15 +639,15 @@ describe('ReactCompositeComponent', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Component has a method called ' +
'componentDidUnmount(). But there is no such lifecycle method. ' +
- 'Did you mean componentWillUnmount()?',
- );
+ 'Did you mean componentWillUnmount()?\n' +
+ ' in Component (at **)',
+ ]);
});
it('should warn when componentDidReceiveProps method is defined', () => {
@@ -660,17 +661,17 @@ describe('ReactCompositeComponent', () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Component has a method called ' +
'componentDidReceiveProps(). But there is no such lifecycle method. ' +
'If you meant to update the state in response to changing props, ' +
'use componentWillReceiveProps(). If you meant to fetch data or ' +
- 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().',
- );
+ 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().\n' +
+ ' in Component (at **)',
+ ]);
});
it('should warn when defaultProps was defined as an instance property', () => {
@@ -686,14 +687,14 @@ describe('ReactCompositeComponent', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Setting defaultProps as an instance property on Component is not supported ' +
- 'and will be ignored. Instead, define defaultProps as a static property on Component.',
- );
+ 'and will be ignored. Instead, define defaultProps as a static property on Component.\n' +
+ ' in Component (at **)',
+ ]);
});
it('should skip update when rerendering element in container', async () => {
@@ -739,16 +740,16 @@ describe('ReactCompositeComponent', () => {
}
}
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Render methods should be a pure function of props and state; ' +
'triggering nested component updates from render is not allowed. If ' +
- 'necessary, trigger nested updates in componentDidUpdate.\n\nCheck the ' +
- 'render method of Outer.',
- );
+ 'necessary, trigger nested updates in componentDidUpdate.\n\n' +
+ 'Check the render method of Outer.\n' +
+ ' in Outer (at **)',
+ ]);
});
it('only renders once if updated in componentWillReceiveProps', async () => {
@@ -836,14 +837,14 @@ describe('ReactCompositeComponent', () => {
}
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'When calling super() in `Foo`, make sure to pass ' +
- "up the same props that your component's constructor was passed.",
- );
+ "up the same props that your component's constructor was passed.\n" +
+ ' in Foo (at **)',
+ ]);
});
it('should only call componentWillUnmount once', async () => {
@@ -1185,16 +1186,17 @@ describe('ReactCompositeComponent', () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).rejects.toThrow();
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ }).rejects.toThrow();
+ assertConsoleErrorDev([
'No `render` method found on the RenderTextInvalidConstructor instance: ' +
- 'did you accidentally return an object from the constructor?',
+ 'did you accidentally return an object from the constructor?\n' +
+ ' in RenderTextInvalidConstructor (at **)',
'No `render` method found on the RenderTextInvalidConstructor instance: ' +
- 'did you accidentally return an object from the constructor?',
+ 'did you accidentally return an object from the constructor?\n' +
+ ' in RenderTextInvalidConstructor (at **)',
]);
});
@@ -1210,14 +1212,14 @@ describe('ReactCompositeComponent', () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'It looks like Bad is reassigning its own `this.props` while rendering. ' +
- 'This is not supported and can lead to confusing bugs.',
- );
+ 'This is not supported and can lead to confusing bugs.\n' +
+ ' in Bad (at **)',
+ ]);
});
it('should return error if render is not defined', async () => {
@@ -1225,16 +1227,17 @@ describe('ReactCompositeComponent', () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).rejects.toThrow();
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ }).rejects.toThrow();
+ assertConsoleErrorDev([
'No `render` method found on the RenderTestUndefinedRender instance: ' +
- 'you may have forgotten to define `render`.',
+ 'you may have forgotten to define `render`.\n' +
+ ' in RenderTestUndefinedRender (at **)',
'No `render` method found on the RenderTestUndefinedRender instance: ' +
- 'you may have forgotten to define `render`.',
+ 'you may have forgotten to define `render`.\n' +
+ ' in RenderTestUndefinedRender (at **)',
]);
});
@@ -1386,13 +1389,18 @@ describe('ReactCompositeComponent', () => {
}
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
- 'Cannot update a component (`A`) while rendering a different component (`B`)',
- );
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Cannot update a component (`A`) while rendering a different component (`B`). ' +
+ 'To locate the bad setState() call inside `B`, ' +
+ 'follow the stack trace as described in https://react.dev/link/setstate-in-render\n' +
+ (gate('enableOwnerStacks')
+ ? ''
+ : ' in B (at **)\n' + ' in div (at **)\n') +
+ ' in Parent (at **)',
+ ]);
// We error, but still update the state.
expect(ref.textContent).toBe('1');
diff --git a/packages/react-dom/src/__tests__/ReactCompositeComponentState-test.js b/packages/react-dom/src/__tests__/ReactCompositeComponentState-test.js
index a651a477a8e76..d0d1c36e514a9 100644
--- a/packages/react-dom/src/__tests__/ReactCompositeComponentState-test.js
+++ b/packages/react-dom/src/__tests__/ReactCompositeComponentState-test.js
@@ -17,13 +17,14 @@ let Scheduler;
let assertLog;
let TestComponent;
let testComponentInstance;
+let assertConsoleErrorDev;
describe('ReactCompositeComponent-state', () => {
beforeEach(() => {
React = require('react');
ReactDOM = require('react-dom');
ReactDOMClient = require('react-dom/client');
- act = require('internal-test-utils').act;
+ ({act, assertConsoleErrorDev} = require('internal-test-utils'));
Scheduler = require('scheduler');
const InternalTestUtils = require('internal-test-utils');
@@ -469,15 +470,15 @@ describe('ReactCompositeComponent-state', () => {
root.render();
});
// Update
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Test.componentWillReceiveProps(): Assigning directly to ' +
"this.state is deprecated (except inside a component's constructor). " +
- 'Use setState instead.',
- );
+ 'Use setState instead.\n' +
+ ' in Test (at **)',
+ ]);
assertLog([
'render -- step: 1, extra: true',
@@ -518,15 +519,15 @@ describe('ReactCompositeComponent-state', () => {
// Mount
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Test.componentWillMount(): Assigning directly to ' +
"this.state is deprecated (except inside a component's constructor). " +
- 'Use setState instead.',
- );
+ 'Use setState instead.\n' +
+ ' in Test (at **)',
+ ]);
assertLog([
'render -- step: 3, extra: false',
@@ -566,13 +567,16 @@ describe('ReactCompositeComponent-state', () => {
});
expect(el.textContent).toBe('A');
- expect(() => {
- ReactDOM.flushSync(() => {
- root.render();
- });
- }).toErrorDev(
- "Can't perform a React state update on a component that hasn't mounted yet",
- );
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ "Can't perform a React state update on a component that hasn't mounted yet. " +
+ 'This indicates that you have a side-effect in your render function that ' +
+ 'asynchronously later calls tries to update the component. ' +
+ 'Move this work to useEffect instead.\n' +
+ ' in B (at **)',
+ ]);
});
// @gate !disableLegacyMode
diff --git a/packages/react-dom/src/__tests__/ReactDOM-test.js b/packages/react-dom/src/__tests__/ReactDOM-test.js
index c6c90d1cf15f2..92571ad69e10c 100644
--- a/packages/react-dom/src/__tests__/ReactDOM-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOM-test.js
@@ -14,7 +14,7 @@ let ReactDOM;
let findDOMNode;
let ReactDOMClient;
let ReactDOMServer;
-
+let assertConsoleErrorDev;
let act;
describe('ReactDOM', () => {
@@ -28,7 +28,7 @@ describe('ReactDOM', () => {
ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE
.findDOMNode;
- act = require('internal-test-utils').act;
+ ({act, assertConsoleErrorDev} = require('internal-test-utils'));
});
it('should bubble onSubmit', async () => {
@@ -188,15 +188,14 @@ describe('ReactDOM', () => {
const myDiv = document.createElement('div');
await expect(async () => {
- await expect(async () => {
- await act(() => {
- ReactDOM.render(, myDiv, 'no');
- });
- }).rejects.toThrowError(
- 'Invalid argument passed as callback. Expected a function. Instead ' +
- 'received: no',
- );
- }).toErrorDev(
+ await act(() => {
+ ReactDOM.render(, myDiv, 'no');
+ });
+ }).rejects.toThrowError(
+ 'Invalid argument passed as callback. Expected a function. Instead ' +
+ 'received: no',
+ );
+ assertConsoleErrorDev(
[
'Expected the last optional `callback` argument to be a function. Instead received: no.',
'Expected the last optional `callback` argument to be a function. Instead received: no.',
@@ -205,15 +204,14 @@ describe('ReactDOM', () => {
);
await expect(async () => {
- await expect(async () => {
- await act(() => {
- ReactDOM.render(, myDiv, {foo: 'bar'});
- });
- }).rejects.toThrowError(
- 'Invalid argument passed as callback. Expected a function. Instead ' +
- 'received: [object Object]',
- );
- }).toErrorDev(
+ await act(() => {
+ ReactDOM.render(, myDiv, {foo: 'bar'});
+ });
+ }).rejects.toThrowError(
+ 'Invalid argument passed as callback. Expected a function. Instead ' +
+ 'received: [object Object]',
+ );
+ assertConsoleErrorDev(
[
"Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }",
"Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
@@ -222,15 +220,14 @@ describe('ReactDOM', () => {
);
await expect(async () => {
- await expect(async () => {
- await act(() => {
- ReactDOM.render(, myDiv, new Foo());
- });
- }).rejects.toThrowError(
- 'Invalid argument passed as callback. Expected a function. Instead ' +
- 'received: [object Object]',
- );
- }).toErrorDev(
+ await act(() => {
+ ReactDOM.render(, myDiv, new Foo());
+ });
+ }).rejects.toThrowError(
+ 'Invalid argument passed as callback. Expected a function. Instead ' +
+ 'received: [object Object]',
+ );
+ assertConsoleErrorDev(
[
'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
@@ -257,15 +254,14 @@ describe('ReactDOM', () => {
const myDiv = document.createElement('div');
ReactDOM.render(, myDiv);
await expect(async () => {
- await expect(async () => {
- await act(() => {
- ReactDOM.render(, myDiv, 'no');
- });
- }).rejects.toThrowError(
- 'Invalid argument passed as callback. Expected a function. Instead ' +
- 'received: no',
- );
- }).toErrorDev(
+ await act(() => {
+ ReactDOM.render(, myDiv, 'no');
+ });
+ }).rejects.toThrowError(
+ 'Invalid argument passed as callback. Expected a function. Instead ' +
+ 'received: no',
+ );
+ assertConsoleErrorDev(
[
'Expected the last optional `callback` argument to be a function. Instead received: no.',
'Expected the last optional `callback` argument to be a function. Instead received: no.',
@@ -275,15 +271,14 @@ describe('ReactDOM', () => {
ReactDOM.render(, myDiv); // Re-mount
await expect(async () => {
- await expect(async () => {
- await act(() => {
- ReactDOM.render(, myDiv, {foo: 'bar'});
- });
- }).rejects.toThrowError(
- 'Invalid argument passed as callback. Expected a function. Instead ' +
- 'received: [object Object]',
- );
- }).toErrorDev(
+ await act(() => {
+ ReactDOM.render(, myDiv, {foo: 'bar'});
+ });
+ }).rejects.toThrowError(
+ 'Invalid argument passed as callback. Expected a function. Instead ' +
+ 'received: [object Object]',
+ );
+ assertConsoleErrorDev(
[
"Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
"Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
@@ -293,15 +288,14 @@ describe('ReactDOM', () => {
ReactDOM.render(, myDiv); // Re-mount
await expect(async () => {
- await expect(async () => {
- await act(() => {
- ReactDOM.render(, myDiv, new Foo());
- });
- }).rejects.toThrowError(
- 'Invalid argument passed as callback. Expected a function. Instead ' +
- 'received: [object Object]',
- );
- }).toErrorDev(
+ await act(() => {
+ ReactDOM.render(, myDiv, new Foo());
+ });
+ }).rejects.toThrowError(
+ 'Invalid argument passed as callback. Expected a function. Instead ' +
+ 'received: [object Object]',
+ );
+ assertConsoleErrorDev(
[
'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
@@ -544,11 +538,10 @@ describe('ReactDOM', () => {
}
const root = ReactDOMClient.createRoot(document.createElement('div'));
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
// ReactDOM(App > div > span)
'Invalid ARIA attribute `ariaTypo`. ARIA attributes follow the pattern aria-* and must be lowercase.\n' +
' in span (at **)\n' +
diff --git a/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js b/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js
index 9b7d9a30cbd53..cd1d055c09d1c 100644
--- a/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js
@@ -13,12 +13,15 @@ describe('ReactDOM unknown attribute', () => {
let React;
let ReactDOMClient;
let act;
+ let assertConsoleErrorDev;
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactDOMClient = require('react-dom/client');
act = require('internal-test-utils').act;
+ assertConsoleErrorDev =
+ require('internal-test-utils').assertConsoleErrorDev;
});
async function testUnknownAttributeRemoval(givenValue) {
@@ -62,12 +65,13 @@ describe('ReactDOM unknown attribute', () => {
});
it('changes values true, false to null, and also warns once', async () => {
- await expect(() => testUnknownAttributeAssignment(true, null)).toErrorDev(
+ await testUnknownAttributeAssignment(true, null);
+ assertConsoleErrorDev([
'Received `true` for a non-boolean attribute `unknown`.\n\n' +
'If you want to write it to the DOM, pass a string instead: ' +
'unknown="true" or unknown={value.toString()}.\n' +
' in div (at **)',
- );
+ ]);
await testUnknownAttributeAssignment(false, null);
});
@@ -92,11 +96,9 @@ describe('ReactDOM unknown attribute', () => {
const el = document.createElement('div');
const root = ReactDOMClient.createRoot(el);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev([]);
+ await act(() => {
+ root.render();
+ });
expect(el.firstChild.getAttribute('inert')).toBe(true ? '' : null);
});
@@ -105,15 +107,15 @@ describe('ReactDOM unknown attribute', () => {
const el = document.createElement('div');
const root = ReactDOMClient.createRoot(el);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev([
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'Received an empty string for a boolean attribute `inert`. ' +
'This will treat the attribute as if it were false. ' +
'Either pass `false` to silence this warning, or ' +
- 'pass `true` if you used an empty string in earlier versions of React to indicate this attribute is true.',
+ 'pass `true` if you used an empty string in earlier versions of React to indicate this attribute is true.\n' +
+ ' in div (at **)',
]);
expect(el.firstChild.getAttribute('inert')).toBe(true ? null : '');
@@ -136,11 +138,12 @@ describe('ReactDOM unknown attribute', () => {
});
it('coerces NaN to strings and warns', async () => {
- await expect(() => testUnknownAttributeAssignment(NaN, 'NaN')).toErrorDev(
+ await testUnknownAttributeAssignment(NaN, 'NaN');
+ assertConsoleErrorDev([
'Received NaN for the `unknown` attribute. ' +
'If this is expected, cast the value to a string.\n' +
' in div (at **)',
- );
+ ]);
});
it('coerces objects to strings and warns', async () => {
@@ -167,52 +170,52 @@ describe('ReactDOM unknown attribute', () => {
}
const test = () =>
testUnknownAttributeAssignment(new TemporalLike(), null);
- await expect(() =>
- expect(test).rejects.toThrowError(new TypeError('prod message')),
- ).toErrorDev(
+
+ await expect(test).rejects.toThrowError(new TypeError('prod message'));
+ assertConsoleErrorDev([
'The provided `unknown` attribute is an unsupported type TemporalLike.' +
- ' This value must be coerced to a string before using it here.',
- );
+ ' This value must be coerced to a string before using it here.\n' +
+ ' in div (at **)',
+ ]);
});
it('removes symbols and warns', async () => {
- await expect(() => testUnknownAttributeRemoval(Symbol('foo'))).toErrorDev(
+ await testUnknownAttributeRemoval(Symbol('foo'));
+ assertConsoleErrorDev([
'Invalid value for prop `unknown` on
tag. Either remove it ' +
'from the element, or pass a string or number value to keep it ' +
'in the DOM. For details, see https://react.dev/link/attribute-behavior \n' +
' in div (at **)',
- );
+ ]);
});
it('removes functions and warns', async () => {
- await expect(() =>
- testUnknownAttributeRemoval(function someFunction() {}),
- ).toErrorDev(
+ await testUnknownAttributeRemoval(function someFunction() {});
+ assertConsoleErrorDev([
'Invalid value for prop `unknown` on
tag. Either remove ' +
'it from the element, or pass a string or number value to ' +
'keep it in the DOM. For details, see ' +
'https://react.dev/link/attribute-behavior \n' +
' in div (at **)',
- );
+ ]);
});
it('allows camelCase unknown attributes and warns', async () => {
const el = document.createElement('div');
- await expect(async () => {
- const root = ReactDOMClient.createRoot(el);
+ const root = ReactDOMClient.createRoot(el);
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'React does not recognize the `helloWorld` prop on a DOM element. ' +
'If you intentionally want it to appear in the DOM as a custom ' +
'attribute, spell it as lowercase `helloworld` instead. ' +
'If you accidentally passed it from a parent component, remove ' +
'it from the DOM element.\n' +
' in div (at **)',
- );
+ ]);
expect(el.firstChild.getAttribute('helloworld')).toBe('something');
});
diff --git a/packages/react-dom/src/__tests__/ReactDOMComponent-test.js b/packages/react-dom/src/__tests__/ReactDOMComponent-test.js
index ce71a6334ee64..65f82dcd3690a 100644
--- a/packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMComponent-test.js
@@ -19,6 +19,7 @@ describe('ReactDOMComponent', () => {
let act;
let assertLog;
let Scheduler;
+ let assertConsoleErrorDev;
beforeEach(() => {
jest.resetModules();
@@ -28,6 +29,8 @@ describe('ReactDOMComponent', () => {
ReactDOMServer = require('react-dom/server');
Scheduler = require('scheduler');
act = require('internal-test-utils').act;
+ assertConsoleErrorDev =
+ require('internal-test-utils').assertConsoleErrorDev;
assertLog = require('internal-test-utils').assertLog;
});
@@ -189,73 +192,72 @@ describe('ReactDOMComponent', () => {
it('should warn for unknown prop', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(
{}} />);
+ });
+ assertConsoleErrorDev([
'Invalid value for prop `foo` on
tag. Either remove it ' +
'from the element, or pass a string or number value to keep ' +
'it in the DOM. For details, see https://react.dev/link/attribute-behavior ' +
'\n in div (at **)',
- );
+ ]);
});
it('should group multiple unknown prop warnings together', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(
{}} baz={() => {}} />);
+ });
+ assertConsoleErrorDev([
'Invalid values for props `foo`, `baz` on
tag. Either remove ' +
'them from the element, or pass a string or number value to keep ' +
'them in the DOM. For details, see https://react.dev/link/attribute-behavior ' +
'\n in div (at **)',
- );
+ ]);
});
it('should warn for onDblClick prop', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render(
{}} />);
- });
- }).toErrorDev(
- 'Invalid event handler property `onDblClick`. Did you mean `onDoubleClick`?\n in div (at **)',
- );
+ await act(() => {
+ root.render(
{}} />);
+ });
+ assertConsoleErrorDev([
+ 'Invalid event handler property `onDblClick`. Did you mean `onDoubleClick`?\n' +
+ ' in div (at **)',
+ ]);
});
it('should warn for unknown string event handlers', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unknown event handler property `onUnknown`. It will be ignored.\n in div (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unknown event handler property `onUnknown`. It will be ignored.\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.hasAttribute('onUnknown')).toBe(false);
expect(container.firstChild.onUnknown).toBe(undefined);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unknown event handler property `onunknown`. It will be ignored.\n in div (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unknown event handler property `onunknown`. It will be ignored.\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.hasAttribute('onunknown')).toBe(false);
expect(container.firstChild.onunknown).toBe(undefined);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unknown event handler property `on-unknown`. It will be ignored.\n in div (at **)',
- );
+
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unknown event handler property `on-unknown`. It will be ignored.\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.hasAttribute('on-unknown')).toBe(false);
expect(container.firstChild['on-unknown']).toBe(undefined);
});
@@ -263,31 +265,31 @@ describe('ReactDOMComponent', () => {
it('should warn for unknown function event handlers', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unknown event handler property `onUnknown`. It will be ignored.\n in div (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unknown event handler property `onUnknown`. It will be ignored.\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.hasAttribute('onUnknown')).toBe(false);
expect(container.firstChild.onUnknown).toBe(undefined);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unknown event handler property `onunknown`. It will be ignored.\n in div (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unknown event handler property `onunknown`. It will be ignored.\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.hasAttribute('onunknown')).toBe(false);
expect(container.firstChild.onunknown).toBe(undefined);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Unknown event handler property `on-unknown`. It will be ignored.\n in div (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Unknown event handler property `on-unknown`. It will be ignored.\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.hasAttribute('on-unknown')).toBe(false);
expect(container.firstChild['on-unknown']).toBe(undefined);
});
@@ -295,13 +297,13 @@ describe('ReactDOMComponent', () => {
it('should warn for badly cased React attributes', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'Invalid DOM property `CHILDREN`. Did you mean `children`?\n in div (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Invalid DOM property `CHILDREN`. Did you mean `children`?\n' +
+ ' in div (at **)',
+ ]);
expect(container.firstChild.getAttribute('CHILDREN')).toBe('5');
});
@@ -323,14 +325,13 @@ describe('ReactDOMComponent', () => {
const style = {fontSize: NaN};
const div = document.createElement('div');
const root = ReactDOMClient.createRoot(div);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- '`NaN` is an invalid value for the `fontSize` css style property.' +
- '\n in span (at **)',
- );
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ '`NaN` is an invalid value for the `fontSize` css style property.\n' +
+ ' in span (at **)',
+ ]);
await act(() => {
root.render();
});
@@ -350,15 +351,18 @@ describe('ReactDOMComponent', () => {
const style = {fontSize: new TemporalLike()};
const root = ReactDOMClient.createRoot(document.createElement('div'));
await expect(async () => {
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'The provided `fontSize` CSS property is an unsupported type TemporalLike.' +
- ' This value must be coerced to a string before using it here.',
- );
+ await act(() => {
+ root.render();
+ });
}).rejects.toThrowError(new TypeError('prod message'));
+ assertConsoleErrorDev([
+ 'The provided `fontSize` CSS property is an unsupported type TemporalLike.' +
+ ' This value must be coerced to a string before using it here.\n' +
+ ' in span (at **)',
+ 'The provided `fontSize` CSS property is an unsupported type TemporalLike.' +
+ ' This value must be coerced to a string before using it here.\n' +
+ ' in span (at **)',
+ ]);
});
it('should update styles if initially null', async () => {
@@ -590,16 +594,16 @@ describe('ReactDOMComponent', () => {
it('should not add an empty src attribute', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'An empty string ("") was passed to the src attribute. ' +
'This may cause the browser to download the whole page again over the network. ' +
'To fix this, either do not render the element at all ' +
- 'or pass null to src instead of an empty string.',
- );
+ 'or pass null to src instead of an empty string.\n' +
+ ' in img (at **)',
+ ]);
const node = container.firstChild;
expect(node.hasAttribute('src')).toBe(false);
@@ -608,31 +612,31 @@ describe('ReactDOMComponent', () => {
});
expect(node.hasAttribute('src')).toBe(true);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'An empty string ("") was passed to the src attribute. ' +
'This may cause the browser to download the whole page again over the network. ' +
'To fix this, either do not render the element at all ' +
- 'or pass null to src instead of an empty string.',
- );
+ 'or pass null to src instead of an empty string.\n' +
+ ' in img (at **)',
+ ]);
expect(node.hasAttribute('src')).toBe(false);
});
it('should not add an empty href attribute', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'An empty string ("") was passed to the href attribute. ' +
'To fix this, either do not render the element at all ' +
- 'or pass null to href instead of an empty string.',
- );
+ 'or pass null to href instead of an empty string.\n' +
+ ' in link (at **)',
+ ]);
const node = container.firstChild;
expect(node.hasAttribute('href')).toBe(false);
@@ -641,15 +645,15 @@ describe('ReactDOMComponent', () => {
});
expect(node.hasAttribute('href')).toBe(true);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
'An empty string ("") was passed to the href attribute. ' +
'To fix this, either do not render the element at all ' +
- 'or pass null to href instead of an empty string.',
- );
+ 'or pass null to href instead of an empty string.\n' +
+ ' in link (at **)',
+ ]);
expect(node.hasAttribute('href')).toBe(false);
});
@@ -871,204 +875,235 @@ describe('ReactDOMComponent', () => {
});
it('should reject attribute key injection attack on markup for regular DOM (SSR)', () => {
- expect(() => {
- for (let i = 0; i < 3; i++) {
- const element1 = React.createElement(
- 'div',
- {'blah" onclick="beevil" noise="hi': 'selected'},
- null,
- );
- const element2 = React.createElement(
- 'div',
- {'>