From 8bb592e9d9882133da25455fa84d4cf8fcaf5406 Mon Sep 17 00:00:00 2001 From: Rob Stanford Date: Mon, 17 Apr 2023 12:48:45 +0100 Subject: [PATCH 1/3] fix: add buffer require shim --- packages/runtime/src/templates/edge/shims.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/runtime/src/templates/edge/shims.js b/packages/runtime/src/templates/edge/shims.js index 04a02389f9..ab4d651393 100644 --- a/packages/runtime/src/templates/edge/shims.js +++ b/packages/runtime/src/templates/edge/shims.js @@ -2,6 +2,7 @@ // deno-lint-ignore-file no-var prefer-const no-unused-vars no-explicit-any import { decode as _base64Decode } from 'https://deno.land/std@0.175.0/encoding/base64.ts' import { AsyncLocalStorage as ALSCompat } from 'https://deno.land/std@0.175.0/node/async_hooks.ts' +import { Buffer as BufferCompat } from 'https://deno.land/std@0.175.0/io/buffer.ts' /** * These are the shims, polyfills and other kludges to make Next.js work in standards-compliant runtime. @@ -48,6 +49,15 @@ const fetch /* type {typeof globalThis.fetch} */ = async (url, init) => { } } +if (typeof require === 'undefined') { + globalThis.require = (name) => { + if (name === 'buffer' || name === 'node:buffer') { + return { Buffer: BufferCompat } + } + throw new ReferenceError('require is not defined') + } +} + // Next edge runtime uses "self" as a function-scoped global-like object, but some of the older polyfills expect it to equal globalThis // See https://nextjs.org/docs/basic-features/supported-browsers-features#polyfills const self = { ...globalThis, fetch } From f4ce7277c4ffbf7f7af77db5e9d79cae7ffc2889 Mon Sep 17 00:00:00 2001 From: Rob Stanford Date: Mon, 17 Apr 2023 12:50:14 +0100 Subject: [PATCH 2/3] chore: add comment for buffer require shim --- packages/runtime/src/templates/edge/shims.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/runtime/src/templates/edge/shims.js b/packages/runtime/src/templates/edge/shims.js index ab4d651393..ce2fd9368e 100644 --- a/packages/runtime/src/templates/edge/shims.js +++ b/packages/runtime/src/templates/edge/shims.js @@ -49,6 +49,7 @@ const fetch /* type {typeof globalThis.fetch} */ = async (url, init) => { } } +// Turbopack aliases "Buffer" to a module import, so we need to provide a shim for that if (typeof require === 'undefined') { globalThis.require = (name) => { if (name === 'buffer' || name === 'node:buffer') { From 409354dc9a760da435ce4b5f1a222275835e64fb Mon Sep 17 00:00:00 2001 From: Rob Stanford Date: Tue, 2 May 2023 19:03:54 +0100 Subject: [PATCH 3/3] feat: shim additional native modules --- packages/runtime/src/templates/edge/shims.js | 29 ++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/runtime/src/templates/edge/shims.js b/packages/runtime/src/templates/edge/shims.js index ce2fd9368e..b52983c27c 100644 --- a/packages/runtime/src/templates/edge/shims.js +++ b/packages/runtime/src/templates/edge/shims.js @@ -1,8 +1,11 @@ // @ts-check -// deno-lint-ignore-file no-var prefer-const no-unused-vars no-explicit-any +// deno-lint-ignore-file prefer-const no-unused-vars import { decode as _base64Decode } from 'https://deno.land/std@0.175.0/encoding/base64.ts' -import { AsyncLocalStorage as ALSCompat } from 'https://deno.land/std@0.175.0/node/async_hooks.ts' -import { Buffer as BufferCompat } from 'https://deno.land/std@0.175.0/io/buffer.ts' +import BufferCompat from 'https://deno.land/std@0.175.0/node/buffer.ts' +import EventsCompat from 'https://deno.land/std@0.175.0/node/events.ts' +import AsyncHooksCompat from 'https://deno.land/std@0.175.0/node/async_hooks.ts' +import AssertCompat from 'https://deno.land/std@0.175.0/node/assert.ts' +import UtilCompat from 'https://deno.land/std@0.175.0/node/util.ts' /** * These are the shims, polyfills and other kludges to make Next.js work in standards-compliant runtime. @@ -19,7 +22,7 @@ globalThis.EdgeRuntime = 'netlify-edge' let _ENTRIES = {} // Next.js expects this as a global -globalThis.AsyncLocalStorage = ALSCompat +globalThis.AsyncLocalStorage = AsyncHooksCompat.AsyncLocalStorage // Next.js uses this extension to the Headers API implemented by Cloudflare workerd if (!('getAll' in Headers.prototype)) { @@ -49,13 +52,23 @@ const fetch /* type {typeof globalThis.fetch} */ = async (url, init) => { } } -// Turbopack aliases "Buffer" to a module import, so we need to provide a shim for that +// Shim native modules that Vercel makes available if (typeof require === 'undefined') { globalThis.require = (name) => { - if (name === 'buffer' || name === 'node:buffer') { - return { Buffer: BufferCompat } + switch (name.replace(/^node:/, '')) { + case 'buffer': + return BufferCompat + case 'events': + return EventsCompat + case 'async_hooks': + return AsyncHooksCompat + case 'assert': + return AssertCompat + case 'util': + return UtilCompat + default: + throw new ReferenceError(`Native module not found: ${name}`) } - throw new ReferenceError('require is not defined') } }