From d1a9ca035d94351eea01689a99acf745a7baf9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Thu, 27 Apr 2023 18:38:38 +0200 Subject: [PATCH 1/5] chore: bump minimum Node.js version --- package.json | 2 +- packages/next/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 87ca2d7690554..713cdb07f2fea 100644 --- a/package.json +++ b/package.json @@ -249,7 +249,7 @@ "@types/react-dom": "18.0.11" }, "engines": { - "node": ">=16" + "node": ">=16.15.0" }, "packageManager": "pnpm@7.24.3" } diff --git a/packages/next/package.json b/packages/next/package.json index f75842f08ec4a..096d921130529 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -315,6 +315,6 @@ "caniuse-lite": "1.0.30001406" }, "engines": { - "node": ">=16" + "node": ">=16.15.0" } } From 7e5974c1a99e3d992abb713c25f47226127d2367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Thu, 27 Apr 2023 18:41:47 +0200 Subject: [PATCH 2/5] fix: polyfill `globalThis.crypto` --- packages/next/src/server/next-server.ts | 1 + packages/next/src/server/next.ts | 1 + packages/next/src/server/node-polyfill-crypto.ts | 12 ++++++++++++ 3 files changed, 14 insertions(+) create mode 100644 packages/next/src/server/node-polyfill-crypto.ts diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index c9dc34c6ecc43..37135f0f6b8c5 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -3,6 +3,7 @@ import './require-hook' import './node-polyfill-fetch' import './node-polyfill-form' import './node-polyfill-web-streams' +import './node-polyfill-crypto' import type { TLSSocket } from 'tls' import type { Route, RouterOptions } from './router' diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index af997f4f227f6..867999a701714 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -5,6 +5,7 @@ import type { NextConfigComplete } from './config-shared' import './require-hook' import './node-polyfill-fetch' +import './node-polyfill-crypto' import { default as Server } from './next-server' import * as log from '../build/output/log' import loadConfig from './config' diff --git a/packages/next/src/server/node-polyfill-crypto.ts b/packages/next/src/server/node-polyfill-crypto.ts new file mode 100644 index 0000000000000..204f165872fee --- /dev/null +++ b/packages/next/src/server/node-polyfill-crypto.ts @@ -0,0 +1,12 @@ +// Polyfill crypto() in the Node.js environment + +if (!(global as any).crypto) { + function getCryptoImpl() { + return require('node:crypto').webcrypto + } + Object.defineProperty(global, 'crypto', { + get() { + return getCryptoImpl() + }, + }) +} From f70efc00504fa2da8f27239bd6defea2c8bb26bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Fri, 28 Apr 2023 10:17:32 +0200 Subject: [PATCH 3/5] add tests --- .../app/handler/route.ts | 9 ++++++++ .../crypto-globally-available/app/layout.tsx | 7 ++++++ .../crypto-globally-available/app/page.tsx | 11 ++++++++++ .../crypto-globally-available.test.ts | 22 +++++++++++++++++++ .../crypto-globally-available/next.config.js | 8 +++++++ 5 files changed, 57 insertions(+) create mode 100644 test/e2e/app-dir/crypto-globally-available/app/handler/route.ts create mode 100644 test/e2e/app-dir/crypto-globally-available/app/layout.tsx create mode 100644 test/e2e/app-dir/crypto-globally-available/app/page.tsx create mode 100644 test/e2e/app-dir/crypto-globally-available/crypto-globally-available.test.ts create mode 100644 test/e2e/app-dir/crypto-globally-available/next.config.js diff --git a/test/e2e/app-dir/crypto-globally-available/app/handler/route.ts b/test/e2e/app-dir/crypto-globally-available/app/handler/route.ts new file mode 100644 index 0000000000000..d9e7a3fbea0e4 --- /dev/null +++ b/test/e2e/app-dir/crypto-globally-available/app/handler/route.ts @@ -0,0 +1,9 @@ +export function GET() { + return new Response( + typeof globalThis.crypto === 'object' + ? 'crypto is available' + : 'crypto is not available' + ) +} + +export const runtime = 'nodejs' diff --git a/test/e2e/app-dir/crypto-globally-available/app/layout.tsx b/test/e2e/app-dir/crypto-globally-available/app/layout.tsx new file mode 100644 index 0000000000000..e7077399c03ce --- /dev/null +++ b/test/e2e/app-dir/crypto-globally-available/app/layout.tsx @@ -0,0 +1,7 @@ +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/crypto-globally-available/app/page.tsx b/test/e2e/app-dir/crypto-globally-available/app/page.tsx new file mode 100644 index 0000000000000..2aba2a95f19d9 --- /dev/null +++ b/test/e2e/app-dir/crypto-globally-available/app/page.tsx @@ -0,0 +1,11 @@ +export default function Page() { + return ( +

+ {typeof globalThis.crypto === 'object' + ? 'crypto is available' + : 'crypto is not available'} +

+ ) +} + +export const runtime = 'nodejs' diff --git a/test/e2e/app-dir/crypto-globally-available/crypto-globally-available.test.ts b/test/e2e/app-dir/crypto-globally-available/crypto-globally-available.test.ts new file mode 100644 index 0000000000000..007c61273676d --- /dev/null +++ b/test/e2e/app-dir/crypto-globally-available/crypto-globally-available.test.ts @@ -0,0 +1,22 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'Web Crypto API is available globally', + { + files: __dirname, + }, + ({ next }) => { + // Recommended for tests that need a full browser + it('should be available in Server Components', async () => { + const browser = await next.browser('/') + expect(await browser.elementByCss('p').text()).toBe('crypto is available') + }) + + // In case you need to test the response object + it('should be available in Route Handlers', async () => { + const res = await next.fetch('/handler') + const html = await res.text() + expect(html).toContain('crypto is available') + }) + } +) diff --git a/test/e2e/app-dir/crypto-globally-available/next.config.js b/test/e2e/app-dir/crypto-globally-available/next.config.js new file mode 100644 index 0000000000000..bf49894afd400 --- /dev/null +++ b/test/e2e/app-dir/crypto-globally-available/next.config.js @@ -0,0 +1,8 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = { + experimental: { appDir: true }, +} + +module.exports = nextConfig From 814904be3f483c2ed750bd557158179e9e19c73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Fri, 28 Apr 2023 10:48:47 +0200 Subject: [PATCH 4/5] expose crypto for build --- packages/next/src/build/utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index e74266ca8d870..6ca131c882c1d 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -16,6 +16,7 @@ import type { StaticGenerationAsyncStorage } from '../client/components/static-g import '../server/require-hook' import '../server/node-polyfill-fetch' +import '../server/node-polyfill-crypto' import chalk from 'next/dist/compiled/chalk' import getGzipSize from 'next/dist/compiled/gzip-size' import textTable from 'next/dist/compiled/text-table' From cabb953351525ae8ed8d3227fffbf38e2c44831e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Fri, 28 Apr 2023 10:56:49 +0200 Subject: [PATCH 5/5] set required package.json lower --- package.json | 2 +- packages/next/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 713cdb07f2fea..d5f71e6a682a9 100644 --- a/package.json +++ b/package.json @@ -249,7 +249,7 @@ "@types/react-dom": "18.0.11" }, "engines": { - "node": ">=16.15.0" + "node": ">=16.8.0" }, "packageManager": "pnpm@7.24.3" } diff --git a/packages/next/package.json b/packages/next/package.json index 096d921130529..4cc04866da146 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -315,6 +315,6 @@ "caniuse-lite": "1.0.30001406" }, "engines": { - "node": ">=16.15.0" + "node": ">=16.8.0" } }