From d26017bdb38e8f595a619d18e674ea18d7d73719 Mon Sep 17 00:00:00 2001 From: feugy Date: Mon, 12 Sep 2022 14:04:35 -0700 Subject: [PATCH] chore: iterates on PR comments and improves error reporting --- docs/api-reference/edge-runtime.md | 4 +-- errors/edge-dynamic-code-evaluation.md | 4 +-- errors/middleware-dynamic-wasm-compilation.md | 25 +++++++++++++++++++ .../build/analysis/get-page-static-info.ts | 9 +++++-- .../edge-config-validations/index.test.ts | 2 +- 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 errors/middleware-dynamic-wasm-compilation.md diff --git a/docs/api-reference/edge-runtime.md b/docs/api-reference/edge-runtime.md index 6d0b7f0c8395188..7993c3a6e80f658 100644 --- a/docs/api-reference/edge-runtime.md +++ b/docs/api-reference/edge-runtime.md @@ -139,7 +139,7 @@ The following JavaScript language features are disabled, and **will not work:** - `WebAssembly.compile` - `WebAssembly.instantiate` with [a buffer parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate#primary_overload_%E2%80%94_taking_wasm_binary_code) -In rare cases, your code could contain (or import) some dynamic code evaluation statements which _can not be reached at runtime_ and which can not be removed by threeshaking. +In rare cases, your code could contain (or import) some dynamic code evaluation statements which _can not be reached at runtime_ and which can not be removed by treeshaking. You can relax the check to allow specific files with your Middleware or Edge API Route exported configuration: ```javascript @@ -154,7 +154,7 @@ export const config = { `allowDynamic` is a [glob](https://github.com/micromatch/micromatch#matching-features), or an array of globs, ignoring dynamic code evaluation for specific files. The globs are relative to your application root folder. -Be warned that if these statements are executed on the Edge, _they will throw and fail your route_. +Be warned that if these statements are executed on the Edge, _they will throw and cause a runtime error_. ## Related diff --git a/errors/edge-dynamic-code-evaluation.md b/errors/edge-dynamic-code-evaluation.md index a97dd0e85e85330..29a5e74b6329fb5 100644 --- a/errors/edge-dynamic-code-evaluation.md +++ b/errors/edge-dynamic-code-evaluation.md @@ -28,7 +28,7 @@ export default async function middleware() { } ``` -In rare cases, your code could contain (or import) some dynamic code evaluation statements which _can not be reached at runtime_ and which can not be removed by threeshaking. +In rare cases, your code could contain (or import) some dynamic code evaluation statements which _can not be reached at runtime_ and which can not be removed by treeshaking. You can relax the check to allow specific files with your Middleware or Edge API Route exported [configuration](https://nextjs.org/docs/api-reference/edge-runtime#unsupported-apis). -Be warned that if these statements are executed on the Edge, _they will throw and fail your route_. +Be warned that if these statements are executed on the Edge, _they will throw and cause a runtime error_. diff --git a/errors/middleware-dynamic-wasm-compilation.md b/errors/middleware-dynamic-wasm-compilation.md new file mode 100644 index 000000000000000..7604d85915a8921 --- /dev/null +++ b/errors/middleware-dynamic-wasm-compilation.md @@ -0,0 +1,25 @@ +# Dynamic WASM compilation is not available in Middlewares + +#### Why This Error Occurred + +Compiling WASM binaries dynamically is not allowed in Middlewares. Specifically, +the following APIs are not supported: + +- `WebAssembly.compile` +- `WebAssembly.instantiate` with [a buffer parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate#primary_overload_%E2%80%94_taking_wasm_binary_code) + +#### Possible Ways to Fix It + +Bundle your WASM binaries using `import`: + +```typescript +import { NextResponse } from 'next/server' +import squareWasm from './square.wasm?module' +export default async function middleware() { + const m = await WebAssembly.instantiate(squareWasm) + const answer = m.exports.square(9) + const response = NextResponse.next() + response.headers.set('x-square', answer.toString()) + return response +} +``` diff --git a/packages/next/build/analysis/get-page-static-info.ts b/packages/next/build/analysis/get-page-static-info.ts index 6147cf4bebcd09d..8b6155a86fb54b0 100644 --- a/packages/next/build/analysis/get-page-static-info.ts +++ b/packages/next/build/analysis/get-page-static-info.ts @@ -164,6 +164,7 @@ function getMiddlewareMatchers( } function getMiddlewareConfig( + pageFilePath: string, config: any, nextConfig: NextConfig ): Partial { @@ -182,7 +183,7 @@ function getMiddlewareConfig( matcher(glob) } catch (err) { throw new Error( - `A middleware/edge exported 'config.allowDynamic' is not a valid pattern: ${ + `${pageFilePath} exported 'config.allowDynamic' contains invalid pattern '${glob}': ${ (err as Error).message }` ) @@ -291,7 +292,11 @@ export async function getPageStaticInfo(params: { warnAboutExperimentalEdgeApiFunctions() } - const middlewareConfig = getMiddlewareConfig(config, nextConfig) + const middlewareConfig = getMiddlewareConfig( + page ?? 'middleware/edge API route', + config, + nextConfig + ) return { ssr, diff --git a/test/production/edge-config-validations/index.test.ts b/test/production/edge-config-validations/index.test.ts index 8c4f059195e5980..ef0df8f55d00fcc 100644 --- a/test/production/edge-config-validations/index.test.ts +++ b/test/production/edge-config-validations/index.test.ts @@ -29,7 +29,7 @@ describe('Edge config validations', () => { }) await expect(next.start()).rejects.toThrow('next build failed') expect(next.cliOutput).toMatch( - `exported 'config.allowDynamic' is not a valid pattern: Expected pattern to be a non-empty string` + `/middleware exported 'config.allowDynamic' contains invalid pattern 'true': Expected pattern to be a non-empty string` ) }) })