diff --git a/packages/use-sync-external-store/package.json b/packages/use-sync-external-store/package.json index b79c3501c05f4..58f190549af87 100644 --- a/packages/use-sync-external-store/package.json +++ b/packages/use-sync-external-store/package.json @@ -20,5 +20,9 @@ "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "devDependencies": { + "react-17": "npm:react@^17", + "react-dom-17": "npm:react-dom@^17" } } diff --git a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js index 1488a8aa3de6c..2fe71bf73c528 100644 --- a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js +++ b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js @@ -29,22 +29,21 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { jest.resetModules(); if (gate(flags => flags.enableUseSyncExternalStoreShim)) { - // Remove useSyncExternalStore from the React imports so that we use the - // shim instead. Also removing startTransition, since we use that to - // detect outdated 18 alphas that don't yet include useSyncExternalStore. - // - // Longer term, we'll probably test this branch using an actual build - // of React 17. + // Test the shim against React 17. jest.mock('react', () => { - const { - // eslint-disable-next-line no-unused-vars - startTransition: _, - // eslint-disable-next-line no-unused-vars - useSyncExternalStore: __, - ...otherExports - } = jest.requireActual('react'); - return otherExports; + return jest.requireActual( + __DEV__ + ? 'react-17/umd/react.development.js' + : 'react-17/umd/react.production.min.js', + ); }); + jest.mock('react-dom', () => + jest.requireActual( + __DEV__ + ? 'react-dom-17/umd/react-dom.development.js' + : 'react-dom-17/umd/react-dom.production.min.js', + ), + ); } React = require('react'); @@ -100,6 +99,7 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { // createLegacyRoot directly. return ReactDOMClient.createRoot(container); } else { + // This ReactDOM.render is from the React 17 npm module. ReactDOM.render(null, container); return { render(children) { @@ -594,6 +594,15 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { ); }).toErrorDev( 'The result of getSnapshot should be cached to avoid an infinite loop', + { + withoutStack: gate(flags => { + if (flags.enableUseSyncExternalStoreShim) { + // Stacks don't work when mixing the source and the npm package. + return flags.source; + } + return false; + }), + }, ); }); diff --git a/scripts/jest/setupTests.js b/scripts/jest/setupTests.js index f4db355d43968..09712d587f93f 100644 --- a/scripts/jest/setupTests.js +++ b/scripts/jest/setupTests.js @@ -170,9 +170,14 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { return message; } const re = /react.dev\/errors\/(\d+)?\??([^\s]*)/; - const matches = message.match(re); + let matches = message.match(re); if (!matches || matches.length !== 3) { - return message; + // Some tests use React 17, when the URL was different. + const re17 = /error-decoder.html\?invariant=(\d+)([^\s]*)/; + matches = message.match(re17); + if (!matches || matches.length !== 3) { + return message; + } } const code = parseInt(matches[1], 10); const args = matches[2] diff --git a/yarn.lock b/yarn.lock index 3af220877f0e1..8f0c563e18db9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12838,6 +12838,14 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: prop-types "^15.6.2" scheduler "^0.13.0" +"react-17@npm:react@^17": + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + "react-dom-15@npm:react-dom@^15": version "15.6.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730" @@ -12858,6 +12866,15 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: prop-types "^15.6.2" scheduler "^0.13.0" +"react-dom-17@npm:react-dom@^17": + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + react-is@^16.8.1, react-is@^17.0.1, "react-is@npm:react-is": version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" @@ -13524,6 +13541,14 @@ scheduler@^0.13.0: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"