Skip to content

Commit

Permalink
feat!: drop React 17 support
Browse files Browse the repository at this point in the history
Co-authored-by: Matt Brophy <matt@brophy.org>
  • Loading branch information
MichaelDeBoey and brophdawg11 committed Aug 15, 2023
1 parent ba67f42 commit 95dde05
Show file tree
Hide file tree
Showing 32 changed files with 80 additions and 301 deletions.
8 changes: 8 additions & 0 deletions .changeset/purple-tables-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@remix-run/dev": major
"@remix-run/eslint-config": major
"@remix-run/react": major
"@remix-run/testing": major
---

Drop React 17 support
11 changes: 1 addition & 10 deletions docs/guides/migrating-react-router-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,7 @@ function handleBrowserRequest(
}
```

If you are using React 17, your client entrypoint will look like this:

```tsx filename=app/entry.client.tsx lines=[2,4]
import { RemixBrowser } from "@remix-run/react";
import { hydrate } from "react-dom";

hydrate(<RemixBrowser />, document);
```

In React 18, you'll use `hydrateRoot` instead of `hydrate`.
Your client entrypoint will look like this:

```tsx filename=app/entry.client.tsx
import { RemixBrowser } from "@remix-run/react";
Expand Down
8 changes: 4 additions & 4 deletions docs/guides/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ The Remix compiler will not do any type checking (it simply removes the types).
"@remix-run/node": "latest",
"@remix-run/react": "latest",
"@remix-run/serve": "latest",
"react": "^17.0.2",
"react-dom": "^17.0.2"
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@remix-run/dev": "latest",
"@remix-run/eslint-config": "latest",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"eslint": "^8.23.1",
"typescript": "^5.1.6"
},
Expand Down
53 changes: 1 addition & 52 deletions integration/server-entry-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";

import { createFixture, js, json } from "./helpers/create-fixture.js";
import { createFixture, js } from "./helpers/create-fixture.js";
import type { Fixture } from "./helpers/create-fixture.js";
import { selectHtml } from "./helpers/playwright-fixture.js";

Expand Down Expand Up @@ -62,54 +62,3 @@ test.describe("Default Server Entry", () => {
expect(selectHtml(await response.text(), "p")).toBe("<p>Hello World</p>");
});
});

test.describe("Default Server Entry (React 17)", () => {
let fixture: Fixture;

test.beforeAll(async () => {
fixture = await createFixture({
files: {
"app/routes/_index.tsx": js`
export default function () {
return <p>Hello World</p>
}
`,
"package.json": json({
name: "remix-template-remix",
private: true,
sideEffects: false,
type: "module",
scripts: {
build:
"node ../../../build/node_modules/@remix-run/dev/dist/cli.js build",
dev: "node ../../../build/node_modules/@remix-run/dev/dist/cli.js dev",
start:
"node ../../../build/node_modules/@remix-run/serve/dist/cli.js build",
},
dependencies: {
"@remix-run/node": "0.0.0-local-version",
"@remix-run/react": "0.0.0-local-version",
"@remix-run/serve": "0.0.0-local-version",
isbot: "0.0.0-local-version",
react: "17.0.2",
"react-dom": "17.0.2",
},
devDependencies: {
"@remix-run/dev": "0.0.0-local-version",
"@types/react": "0.0.0-local-version",
"@types/react-dom": "0.0.0-local-version",
typescript: "0.0.0-local-version",
},
engines: {
node: ">=18.0.0",
},
}),
},
});
});

test("renders", async () => {
let response = await fixture.requestDocument("/");
expect(selectHtml(await response.text(), "p")).toBe("<p>Hello World</p>");
});
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@
"@types/jest": "^27.4.1",
"@types/jsonfile": "^6.1.0",
"@types/lodash": "^4.14.182",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@types/react-test-renderer": "^18.0.0",
"@types/retry": "^0.12.0",
"@types/semver": "^7.3.4",
Expand Down
4 changes: 2 additions & 2 deletions packages/remix-dev/__tests__/fixtures/cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"@cloudflare/workers-types": "^3.18.0",
"@remix-run/dev": "^1.12.0",
"@remix-run/eslint-config": "^1.12.0",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"eslint": "^8.27.0",
"npm-run-all": "^4.1.5",
"typescript": "^5.1.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@1.9.0",
"@remix-run/dev/server-build": "https://esm.sh/@remix-run/dev@1.9.0/server-build",
"@remix-run/react": "https://esm.sh/@remix-run/react@1.9.0",
"react": "https://esm.sh/react@17.0.2",
"react-dom": "https://esm.sh/react-dom@17.0.2",
"react-dom/server": "https://esm.sh/react-dom@17.0.2/server"
"react": "https://esm.sh/react@18.2.0",
"react-dom": "https://esm.sh/react-dom@18.2.0",
"react-dom/server": "https://esm.sh/react-dom@18.2.0/server"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"devDependencies": {
"@remix-run/dev": "*",
"@types/node": "^18.17.1",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"typescript": "^5.1.6"
},
"engines": {
Expand Down
4 changes: 2 additions & 2 deletions packages/remix-dev/__tests__/fixtures/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"devDependencies": {
"@remix-run/dev": "^1.12.0",
"@remix-run/eslint-config": "^1.12.0",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"eslint": "^8.27.0",
"typescript": "^5.1.6"
},
Expand Down
34 changes: 2 additions & 32 deletions packages/remix-dev/cli/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import fse from "fs-extra";
import getPort, { makeRange } from "get-port";
import prettyMs from "pretty-ms";
import NPMCliPackageJson from "@npmcli/package-json";
import { coerce } from "semver";
import pc from "picocolors";

import * as colors from "../colors";
Expand Down Expand Up @@ -214,20 +213,6 @@ export async function generateEntry(
let pkgJson = await NPMCliPackageJson.load(config.rootDirectory);
let deps = pkgJson.content.dependencies ?? {};

let maybeReactVersion = coerce(deps.react);
if (!maybeReactVersion) {
let react = ["react", "react-dom"];
let list = conjunctionListFormat.format(react);
throw new Error(
`Could not determine React version. Please install the following packages: ${list}`
);
}

let type =
maybeReactVersion.major >= 18 || maybeReactVersion.raw === "0.0.0"
? ("stream" as const)
: ("string" as const);

let serverRuntime = deps["@remix-run/deno"]
? "deno"
: deps["@remix-run/cloudflare"]
Expand All @@ -251,26 +236,11 @@ export async function generateEntry(
return;
}

let clientRenderer = deps["@remix-run/react"] ? "react" : undefined;

if (!clientRenderer) {
console.error(
colors.error(
`Could not determine runtime. Please install the following: @remix-run/react`
)
);
return;
}

let defaultsDirectory = path.resolve(__dirname, "..", "config", "defaults");
let defaultEntryClient = path.resolve(
defaultsDirectory,
`entry.client.${clientRenderer}-${type}.tsx`
);
let defaultEntryClient = path.resolve(defaultsDirectory, "entry.client.tsx");
let defaultEntryServer = path.resolve(
defaultsDirectory,
serverRuntime,
`entry.server.${clientRenderer}-${type}.tsx`
`entry.server.${serverRuntime}.tsx`
);

let isServerEntry = entry === "entry.server";
Expand Down
62 changes: 3 additions & 59 deletions packages/remix-dev/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import path from "node:path";
import { pathToFileURL } from "node:url";
import fse from "fs-extra";
import NPMCliPackageJson from "@npmcli/package-json";
import { coerce } from "semver";
import type { NodePolyfillsOptions as EsbuildPluginsNodeModulesPolyfillOptions } from "esbuild-plugins-node-modules-polyfill";

import type { RouteManifest, DefineRoutesFunction } from "./config/routes";
Expand Down Expand Up @@ -419,7 +418,7 @@ export async function readConfig(
let userEntryServerFile = findEntry(appDirectory, "entry.server");

let entryServerFile: string;
let entryClientFile: string;
let entryClientFile = userEntryClientFile || "entry.client.tsx";

let pkgJson = await NPMCliPackageJson.load(remixRoot);
let deps = pkgJson.content.dependencies ?? {};
Expand Down Expand Up @@ -447,29 +446,7 @@ export async function readConfig(
);
}

let clientRenderer = deps["@remix-run/react"] ? "react" : undefined;

if (!clientRenderer) {
throw new Error(
`Could not determine renderer. Please install the following: @remix-run/react`
);
}

let maybeReactVersion = coerce(deps.react);
if (!maybeReactVersion) {
let react = ["react", "react-dom"];
let list = conjunctionListFormat.format(react);
throw new Error(
`Could not determine React version. Please install the following packages: ${list}`
);
}

let type: "stream" | "string" =
maybeReactVersion.major >= 18 || maybeReactVersion.raw === "0.0.0"
? "stream"
: "string";

if (!deps["isbot"] && type === "stream") {
if (!deps["isbot"]) {
console.log(
"adding `isbot` to your package.json, you should commit this change"
);
Expand All @@ -491,35 +468,7 @@ export async function readConfig(
});
}

entryServerFile = `${serverRuntime}/entry.server.${clientRenderer}-${type}.tsx`;
}

if (userEntryClientFile) {
entryClientFile = userEntryClientFile;
} else {
let clientRenderer = deps["@remix-run/react"] ? "react" : undefined;

if (!clientRenderer) {
throw new Error(
`Could not determine runtime. Please install the following: @remix-run/react`
);
}

let maybeReactVersion = coerce(deps.react);
if (!maybeReactVersion) {
let react = ["react", "react-dom"];
let list = conjunctionListFormat.format(react);
throw new Error(
`Could not determine React version. Please install the following packages: ${list}`
);
}

let type: "stream" | "string" =
maybeReactVersion.major >= 18 || maybeReactVersion.raw === "0.0.0"
? "stream"
: "string";

entryClientFile = `entry.client.${clientRenderer}-${type}.tsx`;
entryServerFile = `entry.server.${serverRuntime}.tsx`;
}

let entryClientFilePath = userEntryClientFile
Expand Down Expand Up @@ -712,11 +661,6 @@ declare namespace Intl {
}
}

let conjunctionListFormat = new Intl.ListFormat("en", {
style: "long",
type: "conjunction",
});

let disjunctionListFormat = new Intl.ListFormat("en", {
style: "long",
type: "disjunction",
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 95dde05

Please sign in to comment.