Skip to content

Commit

Permalink
Drop support for Node 18 and installGlobals (#12171)
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 authored Oct 22, 2024
1 parent f294df8 commit 813497a
Show file tree
Hide file tree
Showing 47 changed files with 100 additions and 213 deletions.
10 changes: 10 additions & 0 deletions .changeset/tidy-pens-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@react-router/express": major
"@react-router/node": major
"@react-router/dev": major
"react-router": major
---

Drop support for Node 18, update minimum Node vestion to 20

- Remove `installGlobals()` as this should no longer be necessary
6 changes: 3 additions & 3 deletions .github/workflows/integration-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[18, 20]"
node_version: "[20, 22]"
browser: '["chromium", "firefox"]'

integration-windows:
Expand All @@ -43,7 +43,7 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "windows-latest"
node_version: "[18, 20]"
node_version: "[20, 22]"
browser: '["msedge"]'

integration-macos:
Expand All @@ -52,5 +52,5 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "macos-latest"
node_version: "[18, 20]"
node_version: "[20, 22]"
browser: '["webkit"]'
2 changes: 1 addition & 1 deletion .github/workflows/integration-pr-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[20]"
node_version: "[22]"
browser: '["chromium"]'
6 changes: 3 additions & 3 deletions .github/workflows/integration-pr-windows-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[20]"
node_version: "[22]"
browser: '["firefox"]'

integration-msedge:
Expand All @@ -30,7 +30,7 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "windows-latest"
node_version: "[20]"
node_version: "[22]"
browser: '["msedge"]'

integration-webkit:
Expand All @@ -39,5 +39,5 @@ jobs:
uses: ./.github/workflows/shared-integration.yml
with:
os: "macos-latest"
node_version: "[20]"
node_version: "[22]"
browser: '["webkit"]'
2 changes: 1 addition & 1 deletion .github/workflows/shared-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
node_version:
required: true
# this is limited to string | boolean | number (https://github.community/t/can-action-inputs-be-arrays/16457)
# but we want to pass an array (node_version: "[18, 20]"),
# but we want to pass an array (node_version: "[20, 22]"),
# so we'll need to manually stringify it for now
type: string
browser:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
fail-fast: false
matrix:
node:
- 18
- 20
- 22

runs-on: ubuntu-latest

Expand Down
38 changes: 38 additions & 0 deletions docs/deploying/custom-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,41 @@ title: Custom Node.js
<docs-warning>
This document is a work in progress. There's not much to see here (yet).
</docs-warning>

## Polyfilling `fetch`

React Router officially supports Active and Maintenance[^1] [Node LTS veleases][node-releases] at any given point in time. Dropping support for End of Life Node versions may be done in a React Router Minor release.

[^1]: Based on timing, React Router may drop support for a Node Maintenance LTS version shortly before it goes end-of-life if it better aligns with a React Router Major SemVer release.

At the time React Router v7 was released, all versions had a usable `fetch` implementation so there is generally no need to polyfill any `fetch` APIs so long as you're on Node 22 or one of the later Node 20 releases.

- Node 22 (Active LTS) has a stable [`fetch`][node-22-fetch] implementation
- Node 20 (Maintenance LTS) has an experimental (but suitable from our testing) [`fetch`][node-20-fetch] implementation

If you do find that you need to polyfill anything, you can do so directly from the [undici] package which node uses internally.

```ts
import {
fetch as nodeFetch,
File as NodeFile,
FormData as NodeFormData,
Headers as NodeHeaders,
Request as NodeRequest,
Response as NodeResponse,
} from "undici";

export function polyfillFetch() {
global.File = NodeFile;
global.Headers = NodeHeaders;
global.Request = NodeRequest;
global.Response = NodeResponse;
global.fetch = nodeFetch;
global.FormData = NodeFormData;
}
```

[node-releases]: https://nodejs.org/en/about/previous-releases
[node-20-fetch]: https://nodejs.org/docs/latest-v20.x/api/globals.html#fetch
[node-22-fetch]: https://nodejs.org/docs/latest-v22.x/api/globals.html#fetch
[undici]: https://github.com/nodejs/undici
3 changes: 0 additions & 3 deletions integration/helpers/create-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
UNSAFE_decodeViaTurboStream as decodeViaTurboStream,
} from "react-router";
import { createRequestHandler as createExpressHandler } from "@react-router/express";
import { installGlobals } from "@react-router/node";

import { viteConfig } from "./vite.js";

Expand Down Expand Up @@ -43,8 +42,6 @@ export function json(value: JsonObject) {
}

export async function createFixture(init: FixtureInit, mode?: ServerMode) {
installGlobals();

let projectDir = await createFixtureProject(init, mode);
let buildPath = url.pathToFileURL(
path.join(projectDir, "build/server/index.js")
Expand Down
2 changes: 1 addition & 1 deletion integration/helpers/node-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@
"typescript": "^5.1.0"
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
}
}
2 changes: 1 addition & 1 deletion integration/helpers/vite-cloudflare-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@
"wrangler": "^3.28.2"
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
}
}
2 changes: 1 addition & 1 deletion integration/helpers/vite-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
}
}
3 changes: 0 additions & 3 deletions integration/helpers/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ export const EXPRESS_SERVER = (args: {
}) =>
String.raw`
import { createRequestHandler } from "@react-router/express";
import { installGlobals } from "@react-router/node";
import express from "express";
installGlobals();
let viteDevServer =
process.env.NODE_ENV === "production"
? undefined
Expand Down
4 changes: 0 additions & 4 deletions integration/vite-basename-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ const customServerFile = ({

return js`
import { createRequestHandler } from "@react-router/express";
import { installGlobals } from "@react-router/node";
import express from "express";
installGlobals();
const viteDevServer =
process.env.NODE_ENV === "production"
Expand Down Expand Up @@ -488,9 +486,7 @@ test.describe("Vite base / React Router basename / express build", async () => {
// Slim server that only serves basename (route) requests from the React Router handler
"server.mjs": String.raw`
import { createRequestHandler } from "@react-router/express";
import { installGlobals } from "@react-router/node";
import express from "express";
installGlobals();
const app = express();
app.all(
Expand Down
1 change: 0 additions & 1 deletion jest/jest.config.shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module.exports = {
),
},
modulePathIgnorePatterns: ignorePatterns,
setupFiles: ["<rootDir>/__tests__/setup.ts"],
testMatch: ["<rootDir>/**/*-test.[jt]s?(x)"],
transform: {
"\\.[jt]sx?$": require.resolve("./transform"),
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
"@types/wait-on": "^5.3.2",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"abort-controller": "^3.0.0",
"babel-jest": "^29.7.0",
"babel-plugin-dev-expression": "^0.2.3",
"babel-plugin-transform-remove-console": "^6.9.4",
Expand Down Expand Up @@ -122,7 +121,7 @@
"vite-tsconfig-paths": "^4.2.2"
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
},
"pnpm": {
"patchedDependencies": {
Expand Down
2 changes: 0 additions & 2 deletions packages/react-router-architect/__tests__/setup.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/react-router-architect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
}
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
},
"files": [
"dist/",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
}
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
},
"files": [
"dist/",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
"typescript": "^5.1.6"
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
}
}
10 changes: 8 additions & 2 deletions packages/react-router-dev/cli/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,15 @@ ${colors.logoBlue("react-router")}
export async function run(argv: string[] = process.argv.slice(2)) {
// Check the node version
let versions = process.versions;
if (versions && versions.node && semver.major(versions.node) < 18) {
let MINIMUM_NODE_VERSION = 20;
if (
versions &&
versions.node &&
semver.major(versions.node) < MINIMUM_NODE_VERSION
) {
throw new Error(
`️🚨 Oops, Node v${versions.node} detected. react-router requires a Node version greater than 18.`
`️🚨 Oops, Node v${versions.node} detected. react-router requires ` +
`a Node version greater than ${MINIMUM_NODE_VERSION}.`
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
}
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
},
"files": [
"dist/",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@
"README.md"
],
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
}
}
2 changes: 0 additions & 2 deletions packages/react-router-express/__tests__/setup.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/react-router-express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
}
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
},
"files": [
"dist/",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-fs-routes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
}
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
},
"files": [
"dist/",
Expand Down
3 changes: 0 additions & 3 deletions packages/react-router-node/__tests__/setup.ts

This file was deleted.

55 changes: 0 additions & 55 deletions packages/react-router-node/globals.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/react-router-node/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export { installGlobals } from "./globals";

export { createFileSessionStorage } from "./sessions/fileStorage";

export {
Expand Down
3 changes: 0 additions & 3 deletions packages/react-router-node/install.ts

This file was deleted.

Loading

0 comments on commit 813497a

Please sign in to comment.