diff --git a/.yarn/patches/react-native-npm-0.68.0-9eb3ecb60a.patch b/.yarn/patches/react-native-npm-0.68.0-9eb3ecb60a.patch deleted file mode 100644 index bb6b711f1e52..000000000000 --- a/.yarn/patches/react-native-npm-0.68.0-9eb3ecb60a.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/jest/preprocessor.js b/jest/preprocessor.js -index f5e34763d840193e243a974e448b619f8f635095..cc6e05ab4c9c25a3d257379a1bf19c21fb9ef5ca 100644 ---- a/jest/preprocessor.js -+++ b/jest/preprocessor.js -@@ -38,7 +38,7 @@ module.exports = { - sourceType: 'script', - ...nodeOptions, - ast: false, -- }).code; -+ }); - } - - const {ast} = transformer.transform({ -@@ -66,8 +66,6 @@ module.exports = { - [require('@babel/plugin-transform-flow-strip-types')], - [ - require('@babel/plugin-proposal-class-properties'), -- // use `this.foo = bar` instead of `this.defineProperty('foo', ...)` -- {loose: true}, - ], - [require('@babel/plugin-transform-computed-properties')], - [require('@babel/plugin-transform-destructuring')], -@@ -112,7 +110,7 @@ module.exports = { - sourceMaps: true, - }, - src, -- ).code; -+ ); - }, - - getCacheKey: (createCacheKeyFunction([ diff --git a/.yarnrc.yml b/.yarnrc.yml index 38f6137f7562..172a2ce7ddc9 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -18,8 +18,6 @@ packageExtensions: peerDependencies: "@babel/preset-env": ^7.1.6 react-native@*: - dependencies: - metro-babel-register: 0.67.0 peerDependencies: "@babel/preset-env": ^7.1.6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 72ea00c8ecb2..0fc8df52ae20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ ### Fixes +- `[babel-jest]` [**BREAKING**] Pass `rootDir` as `root` in Babel's options ([#12689](https://github.com/facebook/jest/pull/12689)) - `[expect]` Move typings of `.not`, `.rejects` and `.resolves` modifiers outside of `Matchers` interface ([#12346](https://github.com/facebook/jest/pull/12346)) - `[expect]` Throw useful error if `expect.extend` is called with invalid matchers ([#12488](https://github.com/facebook/jest/pull/12488)) - `[expect]` Fix `iterableEquality` ignores other properties ([#8359](https://github.com/facebook/jest/pull/8359)) diff --git a/e2e/__tests__/multiProjectRunner.test.ts b/e2e/__tests__/multiProjectRunner.test.ts index c9ad5b0bf811..50dd3d04af21 100644 --- a/e2e/__tests__/multiProjectRunner.test.ts +++ b/e2e/__tests__/multiProjectRunner.test.ts @@ -572,3 +572,41 @@ describe("doesn't bleed module file extensions resolution with multiple workers" expect(stderr).toMatch('PASS project2/__tests__/project2.test.js'); }); }); + +describe('Babel config in individual project works in multi-project', () => { + it('Prj-1 works individually', () => { + const result = runJest('multi-project-babel/prj-1'); + expect(result.stderr).toMatch('PASS ./index.test.js'); + expect(result.exitCode).toBe(0); + }); + it('Prj-2 works individually', () => { + const result = runJest('multi-project-babel/prj-2'); + expect(result.stderr).toMatch('PASS ./index.test.js'); + expect(result.exitCode).toBe(0); + }); + it('Prj-3 works individually', () => { + const result = runJest('multi-project-babel/prj-3'); + expect(result.stderr).toMatch('PASS src/index.test.js'); + expect(result.exitCode).toBe(0); + }); + it('Prj-4 works individually', () => { + const result = runJest('multi-project-babel/prj-4'); + expect(result.stderr).toMatch('PASS src/index.test.js'); + expect(result.exitCode).toBe(0); + }); + it('Prj-5 works individually', () => { + const result = runJest('multi-project-babel/prj-5'); + expect(result.stderr).toMatch('PASS src/index.test.js'); + expect(result.exitCode).toBe(0); + }); + it('All project work when running from multiproject', () => { + const result = runJest('multi-project-babel'); + expect(result.stderr).toMatch('PASS prj-1/index.test.js'); + expect(result.stderr).toMatch('PASS prj-2/index.test.js'); + expect(result.stderr).toMatch('PASS prj-3/src/index.test.js'); + expect(result.stderr).toMatch('PASS prj-4/src/index.test.js'); + expect(result.stderr).toMatch('PASS prj-5/src/index.test.js'); + expect(result.stderr).toMatch('PASS prj-3/src/index.test.js'); + expect(result.exitCode).toBe(0); + }); +}); diff --git a/e2e/global-setup/projects.jest.config.js b/e2e/global-setup/projects.jest.config.js index 9d008ac5cd06..08da804c2003 100644 --- a/e2e/global-setup/projects.jest.config.js +++ b/e2e/global-setup/projects.jest.config.js @@ -15,6 +15,9 @@ module.exports = { globalSetup: '/setup.js', rootDir: path.resolve(__dirname, './project-1'), testMatch: ['/**/*.test.js'], + transform: { + '\\.[jt]sx?$': [require.resolve('babel-jest'), {root: __dirname}], + }, transformIgnorePatterns: ['/node_modules/', '/packages/'], }, { @@ -22,6 +25,9 @@ module.exports = { globalSetup: '/setup.js', rootDir: path.resolve(__dirname, './project-2'), testMatch: ['/**/*.test.js'], + transform: { + '\\.[jt]sx?$': [require.resolve('babel-jest'), {root: __dirname}], + }, transformIgnorePatterns: ['/node_modules/', '/packages/'], }, ], diff --git a/e2e/multi-project-babel/package.json b/e2e/multi-project-babel/package.json new file mode 100644 index 000000000000..c51f8db5ccfa --- /dev/null +++ b/e2e/multi-project-babel/package.json @@ -0,0 +1,15 @@ +{ + "jest": { + "projects": [ + { + "rootDir": "/prj-1" + }, + { + "rootDir": "/prj-2" + }, + "/prj-3", + "/prj-4", + "/prj-5" + ] + } +} diff --git a/e2e/multi-project-babel/prj-1/babel.config.js b/e2e/multi-project-babel/prj-1/babel.config.js new file mode 100644 index 000000000000..186d686670e3 --- /dev/null +++ b/e2e/multi-project-babel/prj-1/babel.config.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = { + presets: ['@babel/preset-flow'], +}; diff --git a/e2e/multi-project-babel/prj-1/index.js b/e2e/multi-project-babel/prj-1/index.js new file mode 100644 index 000000000000..881ff4073178 --- /dev/null +++ b/e2e/multi-project-babel/prj-1/index.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = (text: string) => text; diff --git a/e2e/multi-project-babel/prj-1/index.test.js b/e2e/multi-project-babel/prj-1/index.test.js new file mode 100644 index 000000000000..f0f19c2e9ab9 --- /dev/null +++ b/e2e/multi-project-babel/prj-1/index.test.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const f = require('./'); + +it('Transpiles', () => { + expect(f('test')).toBe('test'); +}); diff --git a/e2e/multi-project-babel/prj-1/package.json b/e2e/multi-project-babel/prj-1/package.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/e2e/multi-project-babel/prj-1/package.json @@ -0,0 +1 @@ +{} diff --git a/e2e/multi-project-babel/prj-2/.babelrc.js b/e2e/multi-project-babel/prj-2/.babelrc.js new file mode 100644 index 000000000000..186d686670e3 --- /dev/null +++ b/e2e/multi-project-babel/prj-2/.babelrc.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = { + presets: ['@babel/preset-flow'], +}; diff --git a/e2e/multi-project-babel/prj-2/index.js b/e2e/multi-project-babel/prj-2/index.js new file mode 100644 index 000000000000..881ff4073178 --- /dev/null +++ b/e2e/multi-project-babel/prj-2/index.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = (text: string) => text; diff --git a/e2e/multi-project-babel/prj-2/index.test.js b/e2e/multi-project-babel/prj-2/index.test.js new file mode 100644 index 000000000000..f0f19c2e9ab9 --- /dev/null +++ b/e2e/multi-project-babel/prj-2/index.test.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const f = require('./'); + +it('Transpiles', () => { + expect(f('test')).toBe('test'); +}); diff --git a/e2e/multi-project-babel/prj-2/package.json b/e2e/multi-project-babel/prj-2/package.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/e2e/multi-project-babel/prj-2/package.json @@ -0,0 +1 @@ +{} diff --git a/e2e/multi-project-babel/prj-3/package.json b/e2e/multi-project-babel/prj-3/package.json new file mode 100644 index 000000000000..2b9231f5dcc3 --- /dev/null +++ b/e2e/multi-project-babel/prj-3/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "rootDir": "src" + } +} diff --git a/e2e/multi-project-babel/prj-3/src/babel.config.js b/e2e/multi-project-babel/prj-3/src/babel.config.js new file mode 100644 index 000000000000..186d686670e3 --- /dev/null +++ b/e2e/multi-project-babel/prj-3/src/babel.config.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = { + presets: ['@babel/preset-flow'], +}; diff --git a/e2e/multi-project-babel/prj-3/src/index.js b/e2e/multi-project-babel/prj-3/src/index.js new file mode 100644 index 000000000000..881ff4073178 --- /dev/null +++ b/e2e/multi-project-babel/prj-3/src/index.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = (text: string) => text; diff --git a/e2e/multi-project-babel/prj-3/src/index.test.js b/e2e/multi-project-babel/prj-3/src/index.test.js new file mode 100644 index 000000000000..f0f19c2e9ab9 --- /dev/null +++ b/e2e/multi-project-babel/prj-3/src/index.test.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const f = require('./'); + +it('Transpiles', () => { + expect(f('test')).toBe('test'); +}); diff --git a/e2e/multi-project-babel/prj-4/.babelrc.js b/e2e/multi-project-babel/prj-4/.babelrc.js new file mode 100644 index 000000000000..186d686670e3 --- /dev/null +++ b/e2e/multi-project-babel/prj-4/.babelrc.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = { + presets: ['@babel/preset-flow'], +}; diff --git a/e2e/multi-project-babel/prj-4/package.json b/e2e/multi-project-babel/prj-4/package.json new file mode 100644 index 000000000000..2b9231f5dcc3 --- /dev/null +++ b/e2e/multi-project-babel/prj-4/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "rootDir": "src" + } +} diff --git a/e2e/multi-project-babel/prj-4/src/index.js b/e2e/multi-project-babel/prj-4/src/index.js new file mode 100644 index 000000000000..881ff4073178 --- /dev/null +++ b/e2e/multi-project-babel/prj-4/src/index.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = (text: string) => text; diff --git a/e2e/multi-project-babel/prj-4/src/index.test.js b/e2e/multi-project-babel/prj-4/src/index.test.js new file mode 100644 index 000000000000..f0f19c2e9ab9 --- /dev/null +++ b/e2e/multi-project-babel/prj-4/src/index.test.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const f = require('./'); + +it('Transpiles', () => { + expect(f('test')).toBe('test'); +}); diff --git a/e2e/multi-project-babel/prj-5/.babelrc.js b/e2e/multi-project-babel/prj-5/.babelrc.js new file mode 100644 index 000000000000..186d686670e3 --- /dev/null +++ b/e2e/multi-project-babel/prj-5/.babelrc.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = { + presets: ['@babel/preset-flow'], +}; diff --git a/e2e/multi-project-babel/prj-5/package.json b/e2e/multi-project-babel/prj-5/package.json new file mode 100644 index 000000000000..2b9231f5dcc3 --- /dev/null +++ b/e2e/multi-project-babel/prj-5/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "rootDir": "src" + } +} diff --git a/e2e/multi-project-babel/prj-5/src/index.js b/e2e/multi-project-babel/prj-5/src/index.js new file mode 100644 index 000000000000..881ff4073178 --- /dev/null +++ b/e2e/multi-project-babel/prj-5/src/index.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = (text: string) => text; diff --git a/e2e/multi-project-babel/prj-5/src/index.test.js b/e2e/multi-project-babel/prj-5/src/index.test.js new file mode 100644 index 000000000000..f0f19c2e9ab9 --- /dev/null +++ b/e2e/multi-project-babel/prj-5/src/index.test.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const f = require('./'); + +it('Transpiles', () => { + expect(f('test')).toBe('test'); +}); diff --git a/examples/react-native/jest.config.js b/examples/react-native/jest.config.js index 4ea28b54a72f..5e3d4871ef83 100644 --- a/examples/react-native/jest.config.js +++ b/examples/react-native/jest.config.js @@ -3,9 +3,6 @@ const {resolve} = require('path'); module.exports = { preset: 'react-native', testEnvironment: 'jsdom', - transform: { - '\\.(js|ts|tsx)$': require.resolve('react-native/jest/preprocessor.js'), - }, // this is specific to the Jest repo, not generally needed (the files we ignore will be in node_modules which is ignored by default) transformIgnorePatterns: [resolve(__dirname, '../../packages')], }; diff --git a/jest.config.mjs b/jest.config.mjs index 6084cf82b9d3..3d5bb0fcddcd 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -48,6 +48,7 @@ export default { '/e2e/custom-*', '/e2e/test-in-root', '/e2e/run-programmatically-multiple-projects', + '/e2e/multi-project-babel', '\\.snap$', '/packages/.*/build', '/packages/.*/src/__tests__/setPrettyPrint.ts', diff --git a/package.json b/package.json index 9d406a9f6d7b..6cc88e839cbd 100644 --- a/package.json +++ b/package.json @@ -165,8 +165,7 @@ "resolutions": { "babel-jest": "workspace:*", "jest": "workspace:*", - "jest-environment-node": "workspace:*", - "react-native": "patch:react-native@npm:0.68.1#.yarn/patches/react-native-npm-0.68.0-9eb3ecb60a.patch" + "jest-environment-node": "workspace:*" }, "packageManager": "yarn@3.2.0" } diff --git a/packages/babel-jest/src/index.ts b/packages/babel-jest/src/index.ts index b48ebe71a40c..e4ac550eaf14 100644 --- a/packages/babel-jest/src/index.ts +++ b/packages/babel-jest/src/index.ts @@ -173,10 +173,11 @@ export const createTransformer: TransformerCreator< filename: string, transformOptions: JestTransformOptions, ): TransformOptions { - const {cwd} = transformOptions.config; - // `cwd` first to allow incoming options to override it + const {cwd, rootDir} = transformOptions.config; + // `cwd` and `root` first to allow incoming options to override it return { cwd, + root: rootDir, ...options, caller: { ...options.caller, diff --git a/packages/jest-runtime/src/__mocks__/createRuntime.js b/packages/jest-runtime/src/__mocks__/createRuntime.js index c562ee7a74fe..b22afc6154bf 100644 --- a/packages/jest-runtime/src/__mocks__/createRuntime.js +++ b/packages/jest-runtime/src/__mocks__/createRuntime.js @@ -37,7 +37,7 @@ const setupModuleNameMapper = (config, rootDir) => { return []; }; -const setupTransform = (config, rootDir) => { +const setupTransform = (config, rootDir, cwd) => { if (config?.transform) { const transform = config.transform; return Object.keys(transform).map(regex => [ @@ -45,28 +45,22 @@ const setupTransform = (config, rootDir) => { path.resolve(rootDir, transform[regex]), ]); } - return [['^.+\\.[jt]sx?$', require.resolve('babel-jest')]]; + return [['^.+\\.[jt]sx?$', require.resolve('babel-jest'), {root: cwd}]]; }; module.exports = async function createRuntime(filename, projectConfig) { const rootDir = path.resolve(path.dirname(filename), 'test_root'); + const cwd = path.resolve(__dirname, '../../../..'); const moduleNameMapper = setupModuleNameMapper(projectConfig, rootDir); - const transform = setupTransform(projectConfig, rootDir); + const transform = setupTransform(projectConfig, rootDir, cwd); projectConfig = makeProjectConfig({ cacheDirectory: getCacheDirectory(), - cwd: path.resolve(__dirname, '..', '..', '..', '..'), + cwd, haste: { - hasteImplModulePath: path.resolve( - __dirname, - '..', - '..', - '..', - 'jest-haste-map', - 'src', - '__tests__', - 'haste_impl.js', + hasteImplModulePath: require.resolve( + '../../../jest-haste-map/src/__tests__/haste_impl.js', ), }, id: `Runtime-${filename.replace(/\W/, '-')}.tests`, diff --git a/yarn.lock b/yarn.lock index 7eaa8f033d71..875b2c9d58df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6812,13 +6812,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-replace-ts-export-assignment@npm:^0.0.2": - version: 0.0.2 - resolution: "babel-plugin-replace-ts-export-assignment@npm:0.0.2" - checksum: da749130fe0479cd9da73f8b3aafc62e05885b12732ce0e25976a7138dad1688a03366791b12633afdd8a702e2018ec01764c4ddb0ed0dbc3783b7e75b1b148a - languageName: node - linkType: hard - "babel-plugin-syntax-trailing-function-commas@npm:^7.0.0-beta.0": version: 7.0.0-beta.0 resolution: "babel-plugin-syntax-trailing-function-commas@npm:7.0.0-beta.0" @@ -15033,24 +15026,6 @@ __metadata: languageName: node linkType: hard -"metro-babel-register@npm:0.67.0": - version: 0.67.0 - resolution: "metro-babel-register@npm:0.67.0" - dependencies: - "@babel/core": ^7.14.0 - "@babel/plugin-proposal-nullish-coalescing-operator": ^7.0.0 - "@babel/plugin-proposal-optional-chaining": ^7.0.0 - "@babel/plugin-syntax-class-properties": ^7.0.0 - "@babel/plugin-transform-flow-strip-types": ^7.0.0 - "@babel/plugin-transform-modules-commonjs": ^7.0.0 - "@babel/preset-typescript": ^7.15.0 - "@babel/register": ^7.0.0 - babel-plugin-replace-ts-export-assignment: ^0.0.2 - escape-string-regexp: ^1.0.5 - checksum: 4aabb6884db027326ca97e8c9f3943e9af9f455439fa7e361002e3c5b5c3600e9f4aae141018bebec7a242f6950f822945fd464fa6f14c134f893d6542afc081 - languageName: node - linkType: hard - "metro-babel-transformer@npm:0.67.0": version: 0.67.0 resolution: "metro-babel-transformer@npm:0.67.0" @@ -18627,50 +18602,6 @@ __metadata: languageName: node linkType: hard -"react-native@patch:react-native@npm:0.68.1#.yarn/patches/react-native-npm-0.68.0-9eb3ecb60a.patch::locator=%40jest%2Fmonorepo%40workspace%3A.": - version: 0.68.1 - resolution: "react-native@patch:react-native@npm%3A0.68.1#.yarn/patches/react-native-npm-0.68.0-9eb3ecb60a.patch::version=0.68.1&hash=c5a757&locator=%40jest%2Fmonorepo%40workspace%3A." - dependencies: - "@jest/create-cache-key-function": ^27.0.1 - "@react-native-community/cli": ^7.0.3 - "@react-native-community/cli-platform-android": ^7.0.1 - "@react-native-community/cli-platform-ios": ^7.0.1 - "@react-native/assets": 1.0.0 - "@react-native/normalize-color": 2.0.0 - "@react-native/polyfills": 2.0.0 - abort-controller: ^3.0.0 - anser: ^1.4.9 - base64-js: ^1.1.2 - deprecated-react-native-prop-types: ^2.3.0 - event-target-shim: ^5.0.1 - hermes-engine: ~0.11.0 - invariant: ^2.2.4 - jsc-android: ^250230.2.1 - metro-react-native-babel-transformer: 0.67.0 - metro-runtime: 0.67.0 - metro-source-map: 0.67.0 - nullthrows: ^1.1.1 - pretty-format: ^26.5.2 - promise: ^8.0.3 - react-devtools-core: ^4.23.0 - react-native-codegen: ^0.0.13 - react-native-gradle-plugin: ^0.0.6 - react-refresh: ^0.4.0 - react-shallow-renderer: 16.14.1 - regenerator-runtime: ^0.13.2 - scheduler: ^0.20.2 - stacktrace-parser: ^0.1.3 - use-subscription: ">=1.0.0 <1.6.0" - whatwg-fetch: ^3.0.0 - ws: ^6.1.4 - peerDependencies: - react: 17.0.2 - bin: - react-native: cli.js - checksum: a1d1ab50269a9b83eb2bcae2b5889cf657a48d9b42f1ea9bc05ae575fca10b1c34e226affbc792e336b2a4b1fc4299030ee7e6b9cdcc25e12990379b18d0bed6 - languageName: node - linkType: hard - "react-refresh@npm:^0.4.0": version: 0.4.3 resolution: "react-refresh@npm:0.4.3"