first commit
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled

This commit is contained in:
Arian Tron
2026-03-10 19:37:31 +03:30
commit 61f56f997c
27684 changed files with 2784175 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
export async function usingEval() {
// eslint-disable-next-line no-eval
return { value: eval('100') }
}
export async function notUsingEval() {
return { value: 100 }
}
export function usingEvalSync() {
// eslint-disable-next-line no-eval
return { value: eval('100') }
}

View File

@@ -0,0 +1,35 @@
// (module
// (type (;0;) (func (param i32) (result i32)))
// (func (;0;) (type 0) (param i32) (result i32)
// local.get 0
// local.get 0
// i32.mul)
// (table (;0;) 0 funcref)
// (memory (;0;) 1)
// (export "memory" (memory 0))
// (export "square" (func 0)))
const SQUARE_WASM_BUFFER = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01,
0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x04, 0x04, 0x01, 0x70, 0x00, 0x00,
0x05, 0x03, 0x01, 0x00, 0x01, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, 0x00,
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00, 0x6c, 0x0b,
])
import squareWasmModule from './square.wasm?module'
export async function usingWebAssemblyCompile(x) {
const module = await WebAssembly.compile(SQUARE_WASM_BUFFER)
const instance = await WebAssembly.instantiate(module, {})
return { value: instance.exports.square(x) }
}
export async function usingWebAssemblyInstantiateWithBuffer(x) {
const { instance } = await WebAssembly.instantiate(SQUARE_WASM_BUFFER, {})
return { value: instance.exports.square(x) }
}
export async function usingWebAssemblyInstantiate(x) {
const instance = await WebAssembly.instantiate(squareWasmModule)
return { value: instance.exports.square(x) }
}

View File

@@ -0,0 +1,55 @@
import { NextResponse } from 'next/server'
import { notUsingEval, usingEval } from './lib/utils'
import {
usingWebAssemblyCompile,
usingWebAssemblyInstantiate,
usingWebAssemblyInstantiateWithBuffer,
} from './lib/wasm'
export async function middleware(request) {
if (request.nextUrl.pathname === '/using-eval') {
return new Response(null, {
headers: { data: JSON.stringify(await usingEval()) },
})
}
if (request.nextUrl.pathname === '/not-using-eval') {
return new Response(null, {
headers: { data: JSON.stringify(await notUsingEval()) },
})
}
if (request.nextUrl.pathname === '/using-webassembly-compile') {
return new Response(null, {
headers: { data: JSON.stringify(await usingWebAssemblyCompile(9)) },
})
}
if (request.nextUrl.pathname === '/using-webassembly-instantiate') {
return new Response(null, {
headers: { data: JSON.stringify(await usingWebAssemblyInstantiate(9)) },
})
}
if (
request.nextUrl.pathname === '/using-webassembly-instantiate-with-buffer'
) {
return new Response(null, {
headers: {
data: JSON.stringify(await usingWebAssemblyInstantiateWithBuffer(9)),
},
})
}
return NextResponse.next()
}
export const config = {
matcher: [
'/using-eval',
'/not-using-eval',
'/using-webassembly-compile',
'/using-webassembly-instantiate',
'/using-webassembly-instantiate-with-buffer',
],
}

View File

@@ -0,0 +1,6 @@
module.exports = {
webpack(config) {
config.experiments = { ...config.experiments, asyncWebAssembly: true }
return config
},
}

View File

@@ -0,0 +1,34 @@
import { notUsingEval, usingEval } from '../../lib/utils'
import {
usingWebAssemblyCompile,
usingWebAssemblyInstantiate,
usingWebAssemblyInstantiateWithBuffer,
} from '../../lib/wasm'
export default async function handler(request) {
const useCase = request.nextUrl.searchParams.get('case')
if (useCase === 'using-eval') {
return Response.json(await usingEval())
}
if (useCase === 'not-using-eval') {
return Response.json(await notUsingEval())
}
if (useCase === 'using-webassembly-compile') {
return Response.json(await usingWebAssemblyCompile(9))
}
if (useCase === 'using-webassembly-instantiate') {
return Response.json(await usingWebAssemblyInstantiate(9))
}
if (useCase === 'using-webassembly-instantiate-with-buffer') {
return Response.json(await usingWebAssemblyInstantiateWithBuffer(9))
}
return Response.json({ ok: true })
}
export const config = { runtime: 'edge' }

View File

@@ -0,0 +1,15 @@
import { usingEvalSync, usingEval } from '../lib/utils'
export async function getServerSideProps() {
return {
props: await usingEval(),
}
}
export default function Page(props) {
return (
<div>
{props.value} and {usingEvalSync().value}
</div>
)
}

View File

@@ -0,0 +1,309 @@
/* eslint-env jest */
import stripAnsi from 'next/dist/compiled/strip-ansi'
import { join } from 'path'
import {
fetchViaHTTP,
findPort,
killApp,
launchApp,
nextBuild,
renderViaHTTP,
waitFor,
} from 'next-test-utils'
const EVAL_ERROR = `Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime`
const DYNAMIC_CODE_ERROR = `Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in Edge Runtime`
const WASM_COMPILE_ERROR = `Dynamic WASM code generation (e. g. 'WebAssembly.compile') not allowed in Edge Runtime`
const WASM_INSTANTIATE_ERROR = `Dynamic WASM code generation ('WebAssembly.instantiate' with a buffer parameter) not allowed in Edge Runtime`
jest.setTimeout(1000 * 60 * 2)
const context: Record<string, any> = {
appDir: join(__dirname, '../'),
}
const isTurbopack = process.env.IS_TURBOPACK_TEST
describe('Page using eval in development mode', () => {
let output = ''
beforeAll(async () => {
context.appPort = await findPort()
context.app = await launchApp(context.appDir, context.appPort, {
onStdout(msg) {
output += msg
},
onStderr(msg) {
output += msg
},
})
})
beforeEach(() => (output = ''))
afterAll(() => killApp(context.app))
it('does not issue dynamic code evaluation warnings', async () => {
const html = await renderViaHTTP(context.appPort, '/')
expect(html).toMatch(/>.*?100.*?and.*?100.*?<\//)
await waitFor(500)
expect(output).not.toContain(EVAL_ERROR)
expect(output).not.toContain(DYNAMIC_CODE_ERROR)
expect(output).not.toContain(WASM_COMPILE_ERROR)
expect(output).not.toContain(WASM_INSTANTIATE_ERROR)
})
})
describe.each([
{
title: 'Middleware',
computeRoute(useCase) {
return `/${useCase}`
},
async extractValue(response) {
return JSON.parse(response.headers.get('data')).value
},
},
{
title: 'Edge route',
computeRoute(useCase) {
return `/api/route?case=${useCase}`
},
async extractValue(response) {
return (await response.json()).value
},
},
])(
'$title usage of dynamic code evaluation',
({ extractValue, computeRoute, title }) => {
;(process.env.TURBOPACK_BUILD ? describe.skip : describe)(
'development mode',
() => {
let output = ''
beforeAll(async () => {
context.appPort = await findPort()
context.app = await launchApp(context.appDir, context.appPort, {
onStdout(msg) {
output += msg
},
onStderr(msg) {
output += msg
},
})
})
beforeEach(() => (output = ''))
afterAll(() => killApp(context.app))
it('shows a warning when running code with eval', async () => {
const res = await fetchViaHTTP(
context.appPort,
computeRoute('using-eval')
)
expect(await extractValue(res)).toEqual(100)
await waitFor(500)
expect(output).toContain(EVAL_ERROR)
if (title === 'Middleware') {
expect(output).toContain(
isTurbopack
? '' +
// TODO(veil): Turbopack duplicates project path
'\n at usingEval (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/lib/utils.js:3:17)' +
'\n at middleware (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/middleware.js:12:54)' +
'\n 1 | export async function usingEval() {'
: '\n at usingEval (../../test/integration/edge-runtime-dynamic-code/lib/utils.js:3:19)' +
'\n at middleware (../../test/integration/edge-runtime-dynamic-code/middleware.js:12:54)' +
// Next.js internal frame. Feel free to adjust.
// Not ignore-listed because we're not in an isolated app and Next.js is symlinked so it's not in node_modules
'\n at eval (../packages/next/dist'
)
} else {
expect(output).toContain(
isTurbopack
? '' +
// TODO(veil): Turbopack duplicates project path
'\n at usingEval (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/lib/utils.js:3:17)' +
'\n at handler (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/pages/api/route.js:12:41)' +
'\n 1 | export async function usingEval() {'
: '\n at usingEval (../../test/integration/edge-runtime-dynamic-code/lib/utils.js:3:19)' +
'\n at handler (../../test/integration/edge-runtime-dynamic-code/pages/api/route.js:12:41)' +
'\n 1 | export async function usingEval() {'
)
}
// Turbopack produces incorrect mappings in the sourcemap.
if (isTurbopack) {
expect(output).toContain(
'' +
"\n> 3 | return { value: eval('100') }" +
'\n | ^'
)
} else {
expect(output).toContain(
'' +
"\n> 3 | return { value: eval('100') }" +
'\n | ^'
)
}
})
it('does not show warning when no code uses eval', async () => {
const res = await fetchViaHTTP(
context.appPort,
computeRoute('not-using-eval')
)
expect(await extractValue(res)).toEqual(100)
await waitFor(500)
expect(output).not.toContain('Dynamic Code Evaluation')
})
it('shows a warning when running WebAssembly.compile', async () => {
const res = await fetchViaHTTP(
context.appPort,
computeRoute('using-webassembly-compile')
)
expect(await extractValue(res)).toEqual(81)
await waitFor(500)
expect(output).toContain(WASM_COMPILE_ERROR)
if (title === 'Middleware') {
// Turbopack produces incorrect mappings in the sourcemap.
expect(output).toContain(
isTurbopack
? '' +
'\n at usingWebAssemblyCompile (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/lib/wasm.js:22:18)' +
'\n at middleware (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/middleware.js:24:68)' +
'\n 20 |' +
'\n 21 | export async function usingWebAssemblyCompile(x) {' +
'\n> 22 | const module = await WebAssembly.compile(SQUARE_WASM_BUFFER)' +
'\n | ^'
: '\n at usingWebAssemblyCompile (../../test/integration/edge-runtime-dynamic-code/lib/wasm.js:22:24)' +
'\n at middleware (../../test/integration/edge-runtime-dynamic-code/middleware.js:24:68)' +
// Next.js internal frame. Feel free to adjust.
// Not ignore-listed because we're not in an isolated app and Next.js is symlinked so it's not in node_modules
'\n at'
)
} else {
// Turbopack produces incorrect mappings in the sourcemap.
expect(output).toContain(
isTurbopack
? '' +
// TODO(veil): Turbopack duplicates project path
'\n at usingWebAssemblyCompile (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/lib/wasm.js:22:18)' +
'\n at handler (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/pages/api/route.js:20:55)' +
'\n 20 |'
: '' +
'\n at usingWebAssemblyCompile (../../test/integration/edge-runtime-dynamic-code/lib/wasm.js:22:24)' +
'\n at handler (../../test/integration/edge-runtime-dynamic-code/pages/api/route.js:20:55)' +
'\n 20 |'
)
// Turbopack produces incorrect mappings in the sourcemap.
if (isTurbopack) {
expect(output).toContain(
'' +
'\n> 22 | const module = await WebAssembly.compile(SQUARE_WASM_BUFFER)' +
'\n | ^'
)
} else {
// TODO(veil): Inconsistent cursor position
expect(output).toContain(
'' +
'\n> 22 | const module = await WebAssembly.compile(SQUARE_WASM_BUFFER)' +
'\n | ^'
)
}
}
})
it('shows a warning when running WebAssembly.instantiate with a buffer parameter', async () => {
const res = await fetchViaHTTP(
context.appPort,
computeRoute('using-webassembly-instantiate-with-buffer')
)
expect(await extractValue(res)).toEqual(81)
await waitFor(500)
expect(output).toContain(WASM_INSTANTIATE_ERROR)
if (title === 'Middleware') {
expect(output).toContain(
isTurbopack
? '' +
'\n at async usingWebAssemblyInstantiateWithBuffer (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/lib/wasm.js:28:24)' +
'\n at async middleware (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/middleware.js:39:30)' +
'\n 26 |\n'
: '' +
'\n at async usingWebAssemblyInstantiateWithBuffer (../../test/integration/edge-runtime-dynamic-code/lib/wasm.js:28:24)' +
'\n at async middleware (../../test/integration/edge-runtime-dynamic-code/middleware.js:39:30)' +
// Next.js internal frame. Feel free to adjust.
// TODO(veil): https://linear.app/vercel/issue/NDX-464
'\n at '
)
expect(stripAnsi(output)).toContain(
'' +
'\n> 28 | const { instance } = await WebAssembly.instantiate(SQUARE_WASM_BUFFER, {})' +
'\n | ^'
)
} else {
expect(output).toContain(
isTurbopack
? '' +
// TODO(veil): Turbopack duplicates project path
'\n at async usingWebAssemblyInstantiateWithBuffer (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/lib/wasm.js:28:24)' +
'\n at async handler (../../test/integration/edge-runtime-dynamic-code/test/integration/edge-runtime-dynamic-code/pages/api/route.js:28:26)' +
'\n 26 |'
: '' +
'\n at async usingWebAssemblyInstantiateWithBuffer (../../test/integration/edge-runtime-dynamic-code/lib/wasm.js:28:24)' +
'\n at async handler (../../test/integration/edge-runtime-dynamic-code/pages/api/route.js:28:26)' +
'\n 26 |'
)
// TODO(veil): Inconsistent cursor position
expect(stripAnsi(output)).toContain(
'' +
'\n> 28 | const { instance } = await WebAssembly.instantiate(SQUARE_WASM_BUFFER, {})' +
'\n | ^'
)
}
})
it('does not show a warning when running WebAssembly.instantiate with a module parameter', async () => {
const res = await fetchViaHTTP(
context.appPort,
computeRoute('using-webassembly-instantiate')
)
expect(await extractValue(res)).toEqual(81)
await waitFor(500)
expect(output).not.toContain(WASM_INSTANTIATE_ERROR)
expect(output).not.toContain('DynamicWasmCodeGenerationWarning')
})
}
)
;(process.env.TURBOPACK_DEV ? describe.skip : describe)(
'production mode',
() => {
let buildResult
beforeAll(async () => {
buildResult = await nextBuild(context.appDir, undefined, {
stderr: true,
stdout: true,
})
})
it('should have middleware warning during build', () => {
if (process.env.IS_TURBOPACK_TEST) {
expect(buildResult.stderr).toContain(`Ecmascript file had an error`)
} else {
expect(buildResult.stderr).toContain(`Failed to compile`)
expect(buildResult.stderr).toContain(
`Used by usingEval, usingEvalSync`
)
expect(buildResult.stderr).toContain(
`Used by usingWebAssemblyCompile`
)
}
expect(buildResult.stderr).toContain(DYNAMIC_CODE_ERROR)
})
}
)
}
)