Skip to content

Commit

Permalink
Add react-router/dom subpath export (#11851)
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 authored Jul 30, 2024
1 parent 183fdb8 commit 626bc84
Show file tree
Hide file tree
Showing 27 changed files with 685 additions and 401 deletions.
12 changes: 12 additions & 0 deletions .changeset/weak-goats-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"react-router": major
---

Add `react-router/dom` subpath export to properly enable `react-dom` as an optional `peerDependency`

- This ensures that we don't blindly `import ReactDOM from "react-dom"` in `<RouterProvider>` in order to access `ReactDOM.flushSync()`, since that would break `createMemoryRouter` use cases in non-DOM environments
- DOM environments should import from `react-router/dom` to get the proper component that makes `ReactDOM.flushSync()` available:
- If you are using the Vite plugin, use this in your `entry.client.tsx`:
- `import { HydratedRouter } from 'react-router/dom'`
- If you are not using the Vite plugin and are manually calling `createBrowserRouter`/`createHashRouter`:
- `import { RouterProvider } from "react-router/dom"`
2 changes: 1 addition & 1 deletion docs/upgrading/vite-component-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ You would rename it to `entry.client.tsx` and have it look like this:
import "./index.css";
import React from "react";
import ReactDOM from "react-dom/client";
import { HydratedRouter } from "react-router";
import { HydratedRouter } from "react-router/dom";

ReactDOM.hydrateRoot(
document,
Expand Down
2 changes: 1 addition & 1 deletion integration/fog-of-war-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ test.describe("Fog of War", () => {
files: {
...getFiles(),
"app/entry.client.tsx": js`
import { HydratedRouter } from "react-router";
import { HydratedRouter } from "react-router/dom";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
startTransition(() => {
Expand Down
14 changes: 7 additions & 7 deletions integration/vite-basename-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ test.describe("Vite base / React Router basename / express dev", async () => {
});

test("works when base and basename are different", async ({ page }) => {
await setup({ base: "/mybase/", basename: "/mybase/app/" });
await workflowDev({ page, cwd, port, basename: "/mybase/app/" });
await setup({ base: "/mybase/", basename: "/mybase/dashboard/" });
await workflowDev({ page, cwd, port, basename: "/mybase/dashboard/" });
});

test("works when basename does not start with base", async ({ page }) => {
Expand Down Expand Up @@ -361,9 +361,9 @@ async function workflowDev({

let isAssetRequest = (url: string) =>
/\.[jt]sx?/.test(url) ||
/@id\/__x00__virtual:/.test(url) ||
/@vite\/client/.test(url) ||
/node_modules\/vite\/dist\/client\/env/.test(url);
/\/@id\/__x00__virtual:/.test(url) ||
/\/@vite\/client/.test(url) ||
/\/@fs\//.test(url);

// verify client asset requests are all under base
expect(
Expand Down Expand Up @@ -413,8 +413,8 @@ test.describe("Vite base / React Router basename / vite build", () => {
});

test("works when base and basename are different", async ({ page }) => {
await setup({ base: "/mybase/", basename: "/mybase/app/" });
await workflowBuild({ page, port, basename: "/mybase/app/" });
await setup({ base: "/mybase/", basename: "/mybase/dashboard/" });
await workflowBuild({ page, port, basename: "/mybase/dashboard/" });
});

test("works when basename does not start with base", async ({ page }) => {
Expand Down
2 changes: 1 addition & 1 deletion integration/vite-css-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const files = {
"app/entry.client.tsx": js`
import "./entry.client.css";
import { HydratedRouter } from "react-router";
import { HydratedRouter } from "react-router/dom";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
Expand Down
2 changes: 1 addition & 1 deletion integration/vite-spa-mode-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ test.describe("SPA Mode", () => {
</html>
`,
"app/entry.client.tsx": js`
import { HydratedRouter } from "react-router";
import { HydratedRouter } from "react-router/dom";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-dev/config/defaults/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { HydratedRouter } from "react-router";
import { HydratedRouter } from "react-router/dom";

startTransition(() => {
hydrateRoot(
Expand Down
3 changes: 2 additions & 1 deletion packages/react-router/__tests__/data-router-no-dom-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

import * as React from "react";
import renderer from "react-test-renderer";
import { RouterProvider, useFetcher } from "../lib/dom/lib";
import { useFetcher } from "../lib/dom/lib";
import { RouterProvider } from "../lib/dom-export/dom-router-provider";
import { createMemoryRouter } from "../lib/components";
import { useLoaderData, useNavigate } from "../lib/hooks";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import * as React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { JSDOM } from "jsdom";

import {
createBrowserRouter,
useNavigate,
useSubmit,
useFetcher,
} from "../../index";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { JSDOM } from "jsdom";

// TODO: figure this out
import { RouterProvider } from "../../lib/dom/lib";
import { RouterProvider } from "../../lib/dom-export/dom-router-provider";

describe("flushSync", () => {
it("wraps useNavigate updates in flushSync when specified", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Outlet,
RouterProvider,
} from "../../../index";
import { HydratedRouter } from "../../../lib/dom/ssr/browser";
import { HydratedRouter } from "../../../lib/dom-export/hydrated-router";
import { FrameworkContext } from "../../../lib/dom/ssr/components";
import invariant from "../../../lib/dom/ssr/invariant";
import { ServerRouter } from "../../../lib/dom/ssr/server";
Expand Down
3 changes: 3 additions & 0 deletions packages/react-router/dom-export.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type { RouterProviderProps } from "./lib/dom-export/dom-router-provider";
export { RouterProvider } from "./lib/dom-export/dom-router-provider";
export { HydratedRouter } from "./lib/dom-export/hydrated-router";
63 changes: 50 additions & 13 deletions packages/react-router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export type {
PathRouteProps,
RouteProps,
RouterProps,
RouterProviderProps,
RoutesProps,
PatchRoutesOnMissFunction as unstable_PatchRoutesOnMissFunction,
} from "./lib/components";
Expand All @@ -99,6 +100,7 @@ export {
Outlet,
Route,
Router,
RouterProvider,
Routes,
createMemoryRouter,
createRoutesFromChildren,
Expand Down Expand Up @@ -144,7 +146,6 @@ export type {
SubmitFunction,
FetcherSubmitFunction,
FetcherWithComponents,
RouterProviderProps,
} from "./lib/dom/lib";
export {
createBrowserRouter,
Expand All @@ -155,7 +156,6 @@ export {
HistoryRouter as unstable_HistoryRouter,
NavLink,
Form,
RouterProvider,
ScrollRestoration,
useLinkClickHandler,
useSearchParams,
Expand Down Expand Up @@ -185,7 +185,6 @@ export {
StaticRouter,
StaticRouterProvider,
} from "./lib/dom/server";
export { HydratedRouter } from "./lib/dom/ssr/browser";
export {
Meta,
Links,
Expand Down Expand Up @@ -338,32 +337,70 @@ export type {
///////////////////////////////////////////////////////////////////////////////

/** @internal */
export { ErrorResponseImpl as UNSAFE_ErrorResponseImpl } from "./lib/router/utils";
export {
createBrowserHistory as UNSAFE_createBrowserHistory,
invariant as UNSAFE_invariant,
} from "./lib/router/history";

/** @internal */
export {
decodeViaTurboStream as UNSAFE_decodeViaTurboStream,
SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol,
} from "./lib/dom/ssr/single-fetch";
export { createRouter as UNSAFE_createRouter } from "./lib/router/router";

/** @internal */
export { ErrorResponseImpl as UNSAFE_ErrorResponseImpl } from "./lib/router/utils";

/** @internal */
export {
DataRouterContext as UNSAFE_DataRouterContext,
DataRouterStateContext as UNSAFE_DataRouterStateContext,
FetchersContext as UNSAFE_FetchersContext,
LocationContext as UNSAFE_LocationContext,
NavigationContext as UNSAFE_NavigationContext,
RouteContext as UNSAFE_RouteContext,
ViewTransitionContext as UNSAFE_ViewTransitionContext,
} from "./lib/context";

/** @internal */
export {
ViewTransitionContext as UNSAFE_ViewTransitionContext,
FetchersContext as UNSAFE_FetchersContext,
useScrollRestoration as UNSAFE_useScrollRestoration,
} from "./lib/dom/lib";
export { mapRouteProperties as UNSAFE_mapRouteProperties } from "./lib/components";

/** @internal */
export { FrameworkContext as UNSAFE_FrameworkContext } from "./lib/dom/ssr/components";

/** @internal */
export type { AssetsManifest as UNSAFE_AssetsManifest } from "./lib/dom/ssr/entry";

/** @internal */
export { deserializeErrors as UNSAFE_deserializeErrors } from "./lib/dom/ssr/errors";

/** @internal */
export { RemixErrorBoundary as UNSAFE_RemixErrorBoundary } from "./lib/dom/ssr/errorBoundaries";

/** @internal */
export {
initFogOfWar as UNSAFE_initFogOfWar,
useFogOFWarDiscovery as UNSAFE_useFogOFWarDiscovery,
} from "./lib/dom/ssr/fog-of-war";

/** @internal */
export type { RouteModules as UNSAFE_RouteModules } from "./lib/dom/ssr/routeModules";

/** @internal */
export {
createClientRoutes as UNSAFE_createClientRoutes,
createClientRoutesWithHMRRevalidationOptOut as UNSAFE_createClientRoutesWithHMRRevalidationOptOut,
shouldHydrateRouteLoader as UNSAFE_shouldHydrateRouteLoader,
} from "./lib/dom/ssr/routes";

/** @internal */
export { getSingleFetchDataStrategy as UNSAFE_getSingleFetchDataStrategy } from "./lib/dom/ssr/single-fetch";

/** @internal */
export {
decodeViaTurboStream as UNSAFE_decodeViaTurboStream,
SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol,
} from "./lib/dom/ssr/single-fetch";

/** @internal */
export { ServerMode as UNSAFE_ServerMode } from "./lib/server-runtime/mode";

/** @internal */
export { useScrollRestoration as UNSAFE_useScrollRestoration } from "./lib/dom/lib";
Loading

0 comments on commit 626bc84

Please sign in to comment.