Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for Node 18 and installGlobals #12171

Merged
merged 7 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading