Skip to content

fix: add require shims #2050

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

Merged
merged 5 commits into from
May 3, 2023
Merged
Changes from 3 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
11 changes: 11 additions & 0 deletions packages/runtime/src/templates/edge/shims.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -48,6 +49,16 @@ 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') {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So many shims. 😅

globalThis.require = (name) => {
if (name === 'buffer' || name === 'node:buffer') {
return { Buffer: BufferCompat }
}
throw new ReferenceError('require is not defined')
Copy link

@nickytonline nickytonline Apr 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll seem weird if we get the error require is not defined given that require is defined. Consdier an error message that mentions a particular module cannot be pulled in via require as that will signal to us that another shim is required.

This will help with E2E canary test runs to signal earlier on exactly what the issue is.

Something along these lines.

Suggested change
throw new ReferenceError('require is not defined')
throw new ReferenceError(`Unable to require module ${name}. A shim for module ${name} may be missing.`)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about matching the Next.js message? throw TypeError('Native module not found: ' + id)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better 😎

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you planning to add shims for the other stuff too?

Do you mean the other stuff in the NativeModuleMap, @ascorbic? I wasn't certain whether that was specific to Vercel's infrastructure?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're all the Node modules that are available in workerd, so which Vercel edge runtime now assumes are available. Buffer is the only on they're using in core Next.js right now (I think), but they're basically telling users that they can use them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ascorbic okay, I'll shim all the things!

}
}

// 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 }