Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion docs/01-app/03-api-reference/07-edge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export const config = {
// allows a single file
'/lib/utilities.js',
// use a glob to allow anything in the function-bind 3rd party module
'/node_modules/function-bind/**',
'**/node_modules/function-bind/**',
],
}
```
Expand Down
2 changes: 1 addition & 1 deletion errors/edge-dynamic-code-evaluation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ You can relax the check to allow specific files with your Middleware [configurat
export const config = {
unstable_allowDynamic: [
'/lib/utilities.js', // allows a single file
'/node_modules/function-bind/**', // use a glob to allow anything in the function-bind 3rd party module
'**/node_modules/function-bind/**', // use a glob to allow anything in the function-bind 3rd party module
],
}
```
Expand Down
4 changes: 3 additions & 1 deletion packages/next/src/build/webpack/plugins/middleware-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,9 @@ function isDynamicCodeEvaluationAllowed(

const name = fileName.replace(rootDir ?? '', '')

return picomatch(middlewareConfig?.unstable_allowDynamic ?? [])(name)
return picomatch(middlewareConfig?.unstable_allowDynamic ?? [], {
dot: true,
})(name)
}

function buildUnsupportedApiError({
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ const context = {
logs: { output: '', stdout: '', stderr: '' },
api: new File(join(__dirname, '../pages/api/route.js')),
middleware: new File(join(__dirname, '../middleware.js')),
lib: new File(join(__dirname, '../lib/index.js')),
lib: new File(
join(
__dirname,
// Simulated .pnpm node_modules path:
'../node_modules/.pnpm/test/node_modules/lib/index.js'
)
),
}
const appOption = {
env: { __NEXT_TEST_WITH_DEVTOOL: 1 },
Expand Down Expand Up @@ -74,7 +80,7 @@ describe('Edge runtime configurable guards', () => {
}
export const config = {
runtime: 'edge',
unstable_allowDynamic: '/lib/**'
unstable_allowDynamic: '**/node_modules/lib/**'
}
`)
await waitFor(500)
Expand Down Expand Up @@ -167,14 +173,14 @@ describe('Edge runtime configurable guards', () => {
url: routeUrl,
init() {
context.api.write(`
import { hasDynamic } from '../../lib'
import { hasDynamic } from 'lib'
export default async function handler(request) {
await hasDynamic()
return Response.json({ result: true })
}
export const config = {
runtime: 'edge',
unstable_allowDynamic: '/lib/**'
unstable_allowDynamic: '**/node_modules/lib/**'
}
`)
context.lib.write(`
Expand All @@ -190,15 +196,15 @@ describe('Edge runtime configurable guards', () => {
init() {
context.middleware.write(`
import { NextResponse } from 'next/server'
import { hasDynamic } from './lib'
import { hasDynamic } from 'lib'

// populated with tests
export default async function () {
await hasDynamic()
return NextResponse.next()
}
export const config = {
unstable_allowDynamic: '/lib/**'
unstable_allowDynamic: '**/node_modules/lib/**'
}
`)
context.lib.write(`
Expand All @@ -207,15 +213,19 @@ describe('Edge runtime configurable guards', () => {
}
`)
},
// TODO: Re-enable when Turbopack applies the middleware dynamic code
// evaluation transforms also to code in node_modules.
skip: Boolean(process.env.TURBOPACK),
},
])('$title with allowed, used dynamic code', ({ init, url }) => {
])('$title with allowed, used dynamic code', ({ init, url, skip }) => {
beforeEach(() => init())

it('still warns in dev at runtime', async () => {
;(skip ? it.skip : it)('still warns in dev at runtime', async () => {
context.app = await launchApp(context.appDir, context.appPort, appOption)
const res = await fetchViaHTTP(context.appPort, url)
await waitFor(500)
// eslint-disable-next-line jest/no-standalone-expect
expect(res.status).toBe(200)
// eslint-disable-next-line jest/no-standalone-expect
expect(context.logs.output).toContain(
`Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime`
)
Expand Down Expand Up @@ -265,14 +275,14 @@ describe('Edge runtime configurable guards', () => {
url: routeUrl,
init() {
context.api.write(`
import { hasUnusedDynamic } from '../../lib'
import { hasUnusedDynamic } from 'lib'
export default async function handler(request) {
await hasUnusedDynamic()
return Response.json({ result: true })
}
export const config = {
runtime: 'edge',
unstable_allowDynamic: '/lib/**'
unstable_allowDynamic: '**/node_modules/lib/**'
}
`)
context.lib.write(`
Expand All @@ -290,14 +300,14 @@ describe('Edge runtime configurable guards', () => {
init() {
context.middleware.write(`
import { NextResponse } from 'next/server'
import { hasUnusedDynamic } from './lib'
import { hasUnusedDynamic } from 'lib'
// populated with tests
export default async function () {
await hasUnusedDynamic()
return NextResponse.next()
}
export const config = {
unstable_allowDynamic: '/lib/**'
unstable_allowDynamic: '**/node_modules/lib/**'
}
`)
context.lib.write(`
Expand Down Expand Up @@ -356,7 +366,7 @@ describe('Edge runtime configurable guards', () => {
url: routeUrl,
init() {
context.api.write(`
import { hasDynamic } from '../../lib'
import { hasDynamic } from 'lib'
export default async function handler(request) {
await hasDynamic()
return Response.json({ result: true })
Expand All @@ -372,14 +382,17 @@ describe('Edge runtime configurable guards', () => {
}
`)
},
// TODO: Re-enable when Turbopack applies the edge runtime transforms also
// to code in node_modules.
skip: Boolean(process.env.TURBOPACK),
},
{
title: 'Middleware using lib',
url: middlewareUrl,
init() {
context.middleware.write(`
import { NextResponse } from 'next/server'
import { hasDynamic } from './lib'
import { hasDynamic } from 'lib'
export default async function () {
await hasDynamic()
return NextResponse.next()
Expand All @@ -394,20 +407,24 @@ describe('Edge runtime configurable guards', () => {
}
`)
},
// TODO: Re-enable when Turbopack applies the middleware dynamic code
// evaluation transforms also to code in node_modules.
skip: Boolean(process.env.TURBOPACK),
},
])('$title with unallowed, used dynamic code', ({ init, url }) => {
])('$title with unallowed, used dynamic code', ({ init, url, skip }) => {
beforeEach(() => init())

it('warns in dev at runtime', async () => {
;(skip ? it.skip : it)('warns in dev at runtime', async () => {
context.app = await launchApp(context.appDir, context.appPort, appOption)
const res = await fetchViaHTTP(context.appPort, url)
await waitFor(500)
// eslint-disable-next-line jest/no-standalone-expect
expect(res.status).toBe(200)
// eslint-disable-next-line jest/no-standalone-expect
expect(context.logs.output).toContain(
`Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime`
)
})
;(process.env.TURBOPACK_DEV ? describe.skip : describe)(
;(skip || process.env.TURBOPACK_DEV ? describe.skip : describe)(
'production mode',
() => {
it('fails to build because of dynamic code evaluation', async () => {
Expand Down Expand Up @@ -446,7 +463,7 @@ describe('Edge runtime configurable guards', () => {
init() {
context.middleware.write(`
import { NextResponse } from 'next/server'
import { returnTrue } from './lib'
import { returnTrue } from 'lib'
export default async function () {
(() => {}) instanceof Function
return NextResponse.next()
Expand Down
Loading