diff --git a/.changeset/good-eels-give.md b/.changeset/good-eels-give.md new file mode 100644 index 000000000000..eef29c392363 --- /dev/null +++ b/.changeset/good-eels-give.md @@ -0,0 +1,8 @@ +--- +'@modern-js/plugin-data-loader': patch +'@modern-js/runtime': patch +'@modern-js/utils': patch +--- + +refactor: guard react-router version consistency +refactor: 保证 react-router 相关包的版本一致性 diff --git a/packages/cli/plugin-data-loader/src/cli/createRequest.ts b/packages/cli/plugin-data-loader/src/cli/createRequest.ts index 96d220effef9..9f7463dfbaea 100644 --- a/packages/cli/plugin-data-loader/src/cli/createRequest.ts +++ b/packages/cli/plugin-data-loader/src/cli/createRequest.ts @@ -2,7 +2,7 @@ /* eslint-disable node/prefer-global/url */ import { compile } from 'path-to-regexp'; import { redirect } from 'react-router-dom'; -import { type UNSAFE_DeferredData as DeferredData } from '@modern-js/utils/runtime/router'; +import { type UNSAFE_DeferredData as DeferredData } from '@modern-js/utils/runtime/remix-router'; import { LOADER_ID_PARAM, DIRECT_PARAM, diff --git a/packages/cli/plugin-data-loader/src/cli/data.ts b/packages/cli/plugin-data-loader/src/cli/data.ts index cdf32d6fafbb..610f2fc2c79a 100644 --- a/packages/cli/plugin-data-loader/src/cli/data.ts +++ b/packages/cli/plugin-data-loader/src/cli/data.ts @@ -13,7 +13,7 @@ import { UNSAFE_DeferredData as DeferredData, AbortedDeferredError, -} from '@modern-js/utils/runtime/router'; +} from '@modern-js/utils/runtime/remix-router'; const DEFERRED_VALUE_PLACEHOLDER_PREFIX = '__deferred_promise:'; export async function parseDeferredReadableStream( diff --git a/packages/cli/plugin-data-loader/src/runtime/index.ts b/packages/cli/plugin-data-loader/src/runtime/index.ts index 7f53e5cc5cff..89f629916817 100644 --- a/packages/cli/plugin-data-loader/src/runtime/index.ts +++ b/packages/cli/plugin-data-loader/src/runtime/index.ts @@ -10,8 +10,8 @@ import { ErrorResponse, UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL, type UNSAFE_DeferredData as DeferredData, - transformNestedRoutes, -} from '@modern-js/utils/runtime/router'; +} from '@modern-js/utils/runtime/remix-router'; +import { transformNestedRoutes } from '@modern-js/utils/runtime/nested-routes'; import { isPlainObject } from '@modern-js/utils/lodash'; import { CONTENT_TYPE_DEFERRED, LOADER_ID_PARAM } from '../common/constants'; import { matchEntry, ServerContext } from '../common/utils'; diff --git a/packages/cli/plugin-data-loader/src/runtime/response.ts b/packages/cli/plugin-data-loader/src/runtime/response.ts index b8c31a93edb3..8e0000597301 100644 --- a/packages/cli/plugin-data-loader/src/runtime/response.ts +++ b/packages/cli/plugin-data-loader/src/runtime/response.ts @@ -11,7 +11,7 @@ import { TextEncoder } from 'util'; import { type UNSAFE_DeferredData as DeferredData, type TrackedPromise, -} from '@modern-js/utils/runtime/router'; +} from '@modern-js/utils/runtime/remix-router'; import { serializeJson } from '@modern-js/utils/runtime-node'; function isTrackedPromise(value: any): value is TrackedPromise { diff --git a/packages/runtime/plugin-runtime/package.json b/packages/runtime/plugin-runtime/package.json index c837086fe24f..81c006504af1 100644 --- a/packages/runtime/plugin-runtime/package.json +++ b/packages/runtime/plugin-runtime/package.json @@ -175,7 +175,6 @@ "invariant": "^2.2.4", "react-helmet": "^6.1.0", "react-is": "^18", - "react-router-dom": "^6.8.1", "react-side-effect": "^2.1.1", "redux-logger": "^3.0.6", "styled-components": "^5.3.1", diff --git a/packages/runtime/plugin-runtime/src/router/runtime/DeferredDataScripts.node.tsx b/packages/runtime/plugin-runtime/src/router/runtime/DeferredDataScripts.node.tsx index 0bc92db992ae..2b9e85dfc605 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/DeferredDataScripts.node.tsx +++ b/packages/runtime/plugin-runtime/src/router/runtime/DeferredDataScripts.node.tsx @@ -1,11 +1,11 @@ /* eslint-disable react/no-danger */ -import { TrackedPromise } from '@modern-js/utils/runtime/router'; +import { type TrackedPromise } from '@modern-js/utils/runtime/remix-router'; import { Suspense, useEffect, useRef, useMemo, useContext } from 'react'; import { Await, UNSAFE_DataRouterContext as DataRouterContext, useAsyncError, -} from 'react-router-dom'; +} from '@modern-js/utils/runtime/router'; import { serializeJson } from '@modern-js/utils/runtime-node'; import { JSX_SHELL_STREAM_END_MARK } from '../../common'; import { serializeErrors } from './utils'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/PrefetchLink.tsx b/packages/runtime/plugin-runtime/src/router/runtime/PrefetchLink.tsx index fdfc7b057fef..2e32bdfa3e6a 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/PrefetchLink.tsx +++ b/packages/runtime/plugin-runtime/src/router/runtime/PrefetchLink.tsx @@ -14,7 +14,7 @@ import { useMatches, NavLink as RouterNavLink, NavLinkProps as RouterNavLinkProps, -} from 'react-router-dom'; +} from '@modern-js/utils/runtime/router'; import { RuntimeReactContext } from '../../core'; import { RouteAssets, RouteManifest } from './types'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/hooks.ts b/packages/runtime/plugin-runtime/src/router/runtime/hooks.ts index 64df1508ebcb..efffd4749ec9 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/hooks.ts +++ b/packages/runtime/plugin-runtime/src/router/runtime/hooks.ts @@ -1,5 +1,5 @@ import { createWaterfall } from '@modern-js/plugin'; -import { RouteObject } from 'react-router-dom'; +import { RouteObject } from '@modern-js/utils/runtime/router'; const modifyRoutes = createWaterfall(); diff --git a/packages/runtime/plugin-runtime/src/router/runtime/index.ts b/packages/runtime/plugin-runtime/src/router/runtime/index.ts index 880f0f37e75c..7caafa157bf9 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/index.ts +++ b/packages/runtime/plugin-runtime/src/router/runtime/index.ts @@ -1,4 +1,4 @@ -import { useRouteLoaderData as useRouteData } from 'react-router-dom'; +import { useRouteLoaderData as useRouteData } from '@modern-js/utils/runtime/router'; import { routerPlugin } from './plugin'; import type { SingleRouteConfig, RouterConfig } from './types'; @@ -78,7 +78,7 @@ export type { Search, ShouldRevalidateFunction, To, -} from 'react-router-dom'; +} from '@modern-js/utils/runtime/router'; // Note: Keep in sync with react-router-dom exports! export { @@ -144,9 +144,7 @@ export { createPath, unstable_useBlocker, unstable_usePrompt, -} from 'react-router-dom'; - -// `react-router-dom` has its own dependency: `@remix-run/router`. -// In order to make sure `plugin-data-loader` and user's loaders(mainly `defer` API) depend on the singleton of `@remix-run/router`, -// we export these API from the same package `@modern-js/utils/runtime`. -export { defer, json, redirect } from '@modern-js/utils/runtime/router'; + defer, + json, + redirect, +} from '@modern-js/utils/runtime/router'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/plugin.node.tsx b/packages/runtime/plugin-runtime/src/router/runtime/plugin.node.tsx index 3bef2cbc5e64..2a70d77a57db 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/plugin.node.tsx +++ b/packages/runtime/plugin-runtime/src/router/runtime/plugin.node.tsx @@ -1,11 +1,11 @@ import React, { useContext } from 'react'; -import { createStaticHandler } from '@modern-js/utils/runtime/router'; +import { createStaticHandler } from '@modern-js/utils/runtime/remix-router'; import { createStaticRouter, StaticRouterProvider, -} from 'react-router-dom/server'; +} from '@modern-js/utils/runtime-node/router'; import hoistNonReactStatics from 'hoist-non-react-statics'; -import { createRoutesFromElements } from 'react-router-dom'; +import { createRoutesFromElements } from '@modern-js/utils/runtime/router'; import { RuntimeReactContext } from '../../core'; import type { Plugin } from '../../core'; import { SSRServerContext } from '../../ssr/serverRender/types'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/plugin.tsx b/packages/runtime/plugin-runtime/src/router/runtime/plugin.tsx index 4056de7fccca..d9e4b09118ea 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/plugin.tsx +++ b/packages/runtime/plugin-runtime/src/router/runtime/plugin.tsx @@ -7,7 +7,7 @@ import { useMatches, useLocation, RouteObject, -} from 'react-router-dom'; +} from '@modern-js/utils/runtime/router'; import hoistNonReactStatics from 'hoist-non-react-statics'; import { parsedJSONFromElement } from '@modern-js/utils/runtime-browser'; import { Plugin } from '../../core'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/server.ts b/packages/runtime/plugin-runtime/src/router/runtime/server.ts index 3fcbb618e5f6..04dcf13142bb 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/server.ts +++ b/packages/runtime/plugin-runtime/src/router/runtime/server.ts @@ -1 +1 @@ -export * from 'react-router-dom/server'; +export * from '@modern-js/utils/runtime-node/router'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/types.ts b/packages/runtime/plugin-runtime/src/router/runtime/types.ts index 14dafb447c11..ca19a13bcdc8 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/types.ts +++ b/packages/runtime/plugin-runtime/src/router/runtime/types.ts @@ -1,4 +1,4 @@ -import type { RouteProps, RouteObject } from 'react-router-dom'; +import type { RouteProps, RouteObject } from '@modern-js/utils/runtime/router'; import { PageRoute, NestedRoute } from '@modern-js/types'; declare global { diff --git a/packages/runtime/plugin-runtime/src/router/runtime/utils.tsx b/packages/runtime/plugin-runtime/src/router/runtime/utils.tsx index 0645e6e387b1..b817f6a147aa 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/utils.tsx +++ b/packages/runtime/plugin-runtime/src/router/runtime/utils.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Route } from 'react-router-dom'; +import { Route, isRouteErrorResponse } from '@modern-js/utils/runtime/router'; import { type NestedRoute, type PageRoute, @@ -7,11 +7,10 @@ import { } from '@modern-js/types'; import { ErrorResponse, - isRouteErrorResponse, - type Router, type StaticHandlerContext, - renderNestedRoute, -} from '@modern-js/utils/runtime/router'; + type Router, +} from '@modern-js/utils/runtime/remix-router'; +import { renderNestedRoute } from '@modern-js/utils/runtime/nested-routes'; import { RouterConfig } from './types'; import { DefaultNotFound } from './DefaultNotFound'; import DeferredDataScripts from './DeferredDataScripts'; diff --git a/packages/runtime/plugin-runtime/src/router/runtime/withRouter.tsx b/packages/runtime/plugin-runtime/src/router/runtime/withRouter.tsx index 480ebff53e8d..059abbde332d 100644 --- a/packages/runtime/plugin-runtime/src/router/runtime/withRouter.tsx +++ b/packages/runtime/plugin-runtime/src/router/runtime/withRouter.tsx @@ -1,7 +1,11 @@ // legacy withRouter import React from 'react'; -import { useLocation, useNavigate, useParams } from 'react-router-dom'; +import { + useLocation, + useNavigate, + useParams, +} from '@modern-js/utils/runtime/router'; export interface WithRouterProps { location: ReturnType; diff --git a/packages/runtime/plugin-runtime/src/runtimeContext.ts b/packages/runtime/plugin-runtime/src/runtimeContext.ts index a603e42d7a33..746fa0bcf4a7 100644 --- a/packages/runtime/plugin-runtime/src/runtimeContext.ts +++ b/packages/runtime/plugin-runtime/src/runtimeContext.ts @@ -1,5 +1,5 @@ import { Store } from '@modern-js-reduck/store'; -import type { StaticHandlerContext } from '@modern-js/utils/runtime/router'; +import type { StaticHandlerContext } from '@modern-js/utils/runtime/remix-router'; import { createContext } from 'react'; import { createLoaderManager } from './core/loader/loaderManager'; import { runtime } from './core/plugin'; diff --git a/packages/runtime/plugin-runtime/src/ssr/serverRender/renderToStream/bulidTemplate.before.ts b/packages/runtime/plugin-runtime/src/ssr/serverRender/renderToStream/bulidTemplate.before.ts index fd33d1beeae0..db83b915e3a6 100644 --- a/packages/runtime/plugin-runtime/src/ssr/serverRender/renderToStream/bulidTemplate.before.ts +++ b/packages/runtime/plugin-runtime/src/ssr/serverRender/renderToStream/bulidTemplate.before.ts @@ -1,6 +1,6 @@ import ReactHelmet, { HelmetData } from 'react-helmet'; // Todo: This import will introduce router code, like remix, even if router config is false -import { matchRoutes } from 'react-router-dom'; +import { matchRoutes } from '@modern-js/utils/runtime/router'; import helmetReplace from '../helmet'; import { RuntimeContext } from '../types'; import { CSS_CHUNKS_PLACEHOLDER } from '../utils'; diff --git a/packages/runtime/plugin-runtime/tests/router/prefetch.test.tsx b/packages/runtime/plugin-runtime/tests/router/prefetch.test.tsx index bf887f00a48c..b875f04e5607 100644 --- a/packages/runtime/plugin-runtime/tests/router/prefetch.test.tsx +++ b/packages/runtime/plugin-runtime/tests/router/prefetch.test.tsx @@ -3,7 +3,7 @@ import { createMemoryRouter, LoaderFunctionArgs, RouterProvider, -} from 'react-router-dom'; +} from '@modern-js/utils/runtime/router'; import { render, fireEvent, act, waitFor } from '@testing-library/react'; import { Link } from '../../src/router'; import { RuntimeReactContext } from '../../src'; diff --git a/packages/toolkit/utils/package.json b/packages/toolkit/utils/package.json index 475a7926217c..adefcf8584fa 100644 --- a/packages/toolkit/utils/package.json +++ b/packages/toolkit/utils/package.json @@ -38,6 +38,14 @@ "jsnext:source": "./src/runtime/router.ts", "default": "./dist/esm/runtime/router.js" }, + "./runtime/remix-router": { + "jsnext:source": "./src/runtime/remixRouter.ts", + "default": "./dist/esm/runtime/remixRouter.js" + }, + "./runtime/nested-routes": { + "jsnext:source": "./src/runtime/nestedRoutes.tsx", + "default": "./dist/esm/runtime/nestedRoutes.js" + }, "./runtime-browser": { "jsnext:source": "./src/runtime-browser/index.ts", "default": "./dist/esm/runtime-browser/index.js" @@ -46,6 +54,10 @@ "jsnext:source": "./src/runtime-node/index.ts", "default": "./dist/esm/runtime-node/index.js" }, + "./runtime-node/router": { + "jsnext:source": "./src/runtime-node/router.ts", + "default": "./dist/esm/runtime-node/router.js" + }, "./universal/constants": { "jsnext:source": "./src/universal/constants.ts", "import": "./dist/esm/universal/constants.js", @@ -104,6 +116,14 @@ "types": "./dist/types/runtime/router.d.ts", "default": "./dist/esm/runtime/router.js" }, + "./runtime/remix-router": { + "types": "./dist/types/runtime/remixRouter.d.ts", + "default": "./dist/esm/runtime/remixRouter.js" + }, + "./runtime/nested-routes": { + "types": "./dist/types/runtime/nestedRoutes.d.ts", + "default": "./dist/esm/runtime/nestedRoutes.js" + }, "./runtime-browser": { "jsnext:source": "./src/runtime-browser/index.d.ts", "default": "./dist/esm/runtime-browser/index.js" @@ -112,6 +132,10 @@ "types": "./dist/types/runtime-node/index.d.ts", "default": "./dist/esm/runtime-node/index.js" }, + "./runtime-node/router": { + "types": "./dist/types/runtime-node/router.d.ts", + "default": "./dist/esm/runtime-node/router.js" + }, "./universal/constants": { "types": "./dist/types/universal/constants.d.ts", "import": "./dist/esm/universal/constants.js", @@ -161,12 +185,21 @@ "runtime/router": [ "./dist/types/runtime/router.d.ts" ], + "runtime/remix-router": [ + "./dist/types/runtime/remixRouter.d.ts" + ], + "runtime/nested-routes": [ + "./dist/types/runtime/nestedRoutes.d.ts" + ], "runtime-browser": [ "./dist/types/runtime-browser/index.d.ts" ], "runtime-node": [ "./dist/types/runtime-node/index.d.ts" ], + "runtime-node/router": [ + "./dist/types/runtime-node/router.d.ts" + ], "universal/constants": [ "./dist/types/universal/constants.d.ts" ], @@ -255,13 +288,13 @@ "caniuse-lite": "^1.0.30001451", "lodash": "^4.17.21", "serialize-javascript": "^6.0.0", - "@remix-run/router": "^1.3.2", + "react-router-dom": "6.11.2", + "@remix-run/router": "1.6.2", "@swc/helpers": "0.5.1" }, "peerDependencies": { "react": ">=17.0.0", - "react-dom": ">=17.0.0", - "react-router-dom": "^6.8.1" + "react-dom": ">=17.0.0" }, "peerDependenciesMeta": { "react": { diff --git a/packages/toolkit/utils/src/runtime-node/router.ts b/packages/toolkit/utils/src/runtime-node/router.ts new file mode 100644 index 000000000000..3fcbb618e5f6 --- /dev/null +++ b/packages/toolkit/utils/src/runtime-node/router.ts @@ -0,0 +1 @@ +export * from 'react-router-dom/server'; diff --git a/packages/toolkit/utils/src/runtime/router.ts b/packages/toolkit/utils/src/runtime/router.ts index da8b8d05199e..5d7bab5b35bc 100644 --- a/packages/toolkit/utils/src/runtime/router.ts +++ b/packages/toolkit/utils/src/runtime/router.ts @@ -1,2 +1 @@ -export * from './nestedRoutes'; -export * from './remixRouter'; +export * from 'react-router-dom'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5cbab1ac5b9..c38a610e7840 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2483,7 +2483,6 @@ importers: react-dom: ^18 react-helmet: ^6.1.0 react-is: ^18 - react-router-dom: ^6.8.1 react-side-effect: ^2.1.1 redux-logger: ^3.0.6 styled-components: ^5.3.1 @@ -2517,7 +2516,6 @@ importers: invariant: 2.2.4 react-helmet: 6.1.0_react@18.2.0 react-is: 18.2.0 - react-router-dom: 6.8.1_biqbaboplfbrettd7655fr4n2y react-side-effect: 2.1.2_react@18.2.0 redux-logger: 3.0.6 styled-components: 5.3.5_7i5myeigehqah43i5u7wbekgba @@ -3564,7 +3562,7 @@ importers: packages/toolkit/utils: specifiers: '@modern-js/types': workspace:* - '@remix-run/router': ^1.3.2 + '@remix-run/router': 1.6.2 '@scripts/build': workspace:* '@scripts/jest-config': workspace:* '@swc/helpers': 0.5.1 @@ -3576,15 +3574,16 @@ importers: lodash: ^4.17.21 react: '>=17.0.0' react-dom: '>=17.0.0' - react-router-dom: ^6.8.1 + react-router-dom: 6.11.2 serialize-javascript: ^6.0.0 typescript: ^5 webpack: ^5.82.1 dependencies: - '@remix-run/router': 1.3.2 + '@remix-run/router': 1.6.2 '@swc/helpers': 0.5.1 caniuse-lite: 1.0.30001451 lodash: 4.17.21 + react-router-dom: 6.11.2_biqbaboplfbrettd7655fr4n2y serialize-javascript: 6.0.0 devDependencies: '@modern-js/types': link:../types @@ -3596,7 +3595,6 @@ importers: jest: 29.5.0_@types+node@14.18.35 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-router-dom: 6.8.1_biqbaboplfbrettd7655fr4n2y typescript: 5.0.4 webpack: 5.82.1 @@ -11169,7 +11167,7 @@ packages: react-router-dom: optional: true dependencies: - '@remix-run/router': 1.3.2 + '@remix-run/router': 1.6.2 caniuse-lite: 1.0.30001451 lodash: 4.17.21 serialize-javascript: 6.0.1 @@ -11644,6 +11642,10 @@ packages: resolution: {integrity: sha512-t54ONhl/h75X94SWsHGQ4G/ZrCEguKSRQr7DrjTciJXW0YU1QhlwYeycvK5JgkzlxmvrK7wq1NB/PLtHxoiDcA==} engines: {node: '>=14'} + /@remix-run/router/1.6.2: + resolution: {integrity: sha512-LzqpSrMK/3JBAVBI9u3NWtOhWNw5AMQfrUFYB0+bDHTSw17z++WJLsPsxAuK+oSddsxk4d7F/JcdDPM1M5YAhA==} + engines: {node: '>=14'} + /@remix-run/server-runtime/1.13.0: resolution: {integrity: sha512-gjIW3XCeIlOt3rrOZMD6HixQydRgs1SwYjP99ZAVruG2+gNq/tL2OusMFYTLvtWrybt215tPROyF/6iTLsaO3g==} engines: {node: '>=14'} @@ -29285,6 +29287,19 @@ packages: tiny-warning: 1.0.3 dev: false + /react-router-dom/6.11.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-JNbKtAeh1VSJQnH6RvBDNhxNwemRj7KxCzc5jb7zvDSKRnPWIFj9pO+eXqjM69gQJ0r46hSz1x4l9y0651DKWw==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.6.2 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-router: 6.11.2_react@18.2.0 + dev: false + /react-router-dom/6.8.1_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-67EXNfkQgf34P7+PSb6VlBuaacGhkKn3kpE51+P6zYSG2kiRoumXEL6e27zTa9+PGF2MNXbgIUHTVlleLbIcHQ==} engines: {node: '>=14'} @@ -29325,6 +29340,16 @@ packages: tiny-warning: 1.0.3 dev: false + /react-router/6.11.2_react@18.2.0: + resolution: {integrity: sha512-74z9xUSaSX07t3LM+pS6Un0T55ibUE/79CzfZpy5wsPDZaea1F8QkrsiyRnA2YQ7LwE/umaydzXZV80iDCPkMg==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.6.2 + react: 18.2.0 + dev: false + /react-router/6.8.1_react@18.2.0: resolution: {integrity: sha512-Jgi8BzAJQ8MkPt8ipXnR73rnD7EmZ0HFFb7jdQU24TynGW1Ooqin2KVDN9voSC+7xhqbbCd2cjGUepb6RObnyg==} engines: {node: '>=14'}