Skip to content

Commit

Permalink
Fix shared layer bundling in Edge Runtime (#51348)
Browse files Browse the repository at this point in the history
Our shared layer matcher doesn't contain `next/dist/esm`, which breaks Server Actions when there're cookie/header accesses.

Closes #50099. Fix NEXT-1229
  • Loading branch information
shuding authored Jun 15, 2023
1 parent a806f1a commit 7d7d5a7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
14 changes: 7 additions & 7 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const babelIncludeRegexes: RegExp[] = [
const reactPackagesRegex = /^(react|react-dom|react-server-dom-webpack)($|\/)/

const asyncStoragesRegex =
/next[\\/]dist[\\/]client[\\/]components[\\/](static-generation-async-storage|action-async-storage|request-async-storage)/
/next[\\/]dist[\\/](esm[\\/])?client[\\/]components[\\/](static-generation-async-storage|action-async-storage|request-async-storage)/

// exports.<conditionName>
const edgeConditionNames = [
Expand Down Expand Up @@ -1894,6 +1894,12 @@ export default async function getBaseWebpackConfig(
rules: [
...(hasAppDir
? [
{
// Make sure that AsyncLocalStorage module instance is shared between server and client
// layers.
layer: WEBPACK_LAYERS.shared,
test: asyncStoragesRegex,
},
{
// All app dir layers need to use this configured resolution logic
issuerLayer: {
Expand Down Expand Up @@ -1957,12 +1963,6 @@ export default async function getBaseWebpackConfig(
loader: 'next-flight-loader',
},
},
{
// Make sure that AsyncLocalStorage module instance is shared between server and client
// layers.
layer: WEBPACK_LAYERS.shared,
test: asyncStoragesRegex,
},
]
: []),
// TODO: FIXME: do NOT webpack 5 support with this
Expand Down
17 changes: 17 additions & 0 deletions test/e2e/app-dir/actions/app-action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,23 @@ createNextDescribe(
return browser.eval('window.location.toString()')
}, 'https://example.com/')
})

it('should allow cookie and header async storages', async () => {
const browser = await next.browser('/client/edge')

const currentTestCookie = await browser.eval(
`document.cookie.match(/test-cookie=(\\d+)/)?.[1]`
)

await browser.elementByCss('#get-headers').click()

await check(async () => {
const newTestCookie = await browser.eval(
`document.cookie.match(/test-cookie=(\\d+)/)?.[1]`
)
return newTestCookie !== currentTestCookie ? 'success' : 'failure'
}, 'success')
})
})

describe('fetch actions', () => {
Expand Down
7 changes: 6 additions & 1 deletion test/e2e/app-dir/actions/app/client/edge/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useState } from 'react'

import double, { inc, dec, redirectAction } from '../actions'
import double, { inc, dec, redirectAction, getHeaders } from '../actions'

export default function Counter() {
const [count, setCount] = useState(0)
Expand Down Expand Up @@ -52,6 +52,11 @@ export default function Counter() {
redirect external
</button>
</form>
<form>
<button id="get-headers" formAction={() => getHeaders()}>
get headers
</button>
</form>
</div>
)
}
Expand Down

0 comments on commit 7d7d5a7

Please sign in to comment.