Skip to content

Commit b659ca6

Browse files
authored
[dev-overlay] ensure stripping overlay bundle in prod build (#76976)
### What While adding a regression test for overlay JS bundle to ensure it's not gonna existed in client bundles by asserting the source map. Found that we're also including the indicator reducer from client JS bundles. This PR ensure we fully strips it out
1 parent 75831c0 commit b659ca6

File tree

3 files changed

+76
-32
lines changed

3 files changed

+76
-32
lines changed

packages/next/src/client/components/use-reducer.ts

+24-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {
77
ReducerActions,
88
ReducerState,
99
} from './router-reducer/router-reducer-types'
10-
import { useSyncDevRenderIndicator } from './react-dev-overlay/utils/dev-indicator/use-sync-dev-render-indicator'
1110

1211
export function useUnwrapState(state: ReducerState): AppRouterState {
1312
// reducer actions can be async, so sometimes we need to suspend until the state is resolved
@@ -23,16 +22,31 @@ export function useReducer(
2322
actionQueue: AppRouterActionQueue
2423
): [ReducerState, Dispatch<ReducerActions>] {
2524
const [state, setState] = React.useState<ReducerState>(actionQueue.state)
26-
const syncDevRenderIndicator = useSyncDevRenderIndicator()
25+
const actionDispatch = (action: ReducerActions) => {
26+
actionQueue.dispatch(action, setState)
27+
}
28+
29+
let syncDevRenderIndicator
30+
if (process.env.NODE_ENV !== 'production') {
31+
const useSyncDevRenderIndicator =
32+
require('./react-dev-overlay/utils/dev-indicator/use-sync-dev-render-indicator')
33+
.useSyncDevRenderIndicator as typeof import('./react-dev-overlay/utils/dev-indicator/use-sync-dev-render-indicator').useSyncDevRenderIndicator
34+
// eslint-disable-next-line react-hooks/rules-of-hooks
35+
syncDevRenderIndicator = useSyncDevRenderIndicator()
36+
}
37+
38+
const dispatchCallback =
39+
process.env.NODE_ENV !== 'production'
40+
? (action: ReducerActions) => {
41+
syncDevRenderIndicator!(() => actionDispatch(action))
42+
}
43+
: actionDispatch
2744

28-
const dispatch = useCallback(
29-
(action: ReducerActions) => {
30-
syncDevRenderIndicator(() => {
31-
actionQueue.dispatch(action, setState)
32-
})
33-
},
34-
[actionQueue, syncDevRenderIndicator]
35-
)
45+
const dispatch = useCallback(dispatchCallback, [
46+
actionQueue,
47+
dispatchCallback,
48+
syncDevRenderIndicator,
49+
])
3650

3751
return [state, dispatch]
3852
}

test/production/app-dir/browser-chunks/browser-chunks.test.ts

+42-22
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,57 @@ import { nextTestSetup } from 'e2e-utils'
33
import { SourceMapPayload } from 'module'
44

55
describe('browser-chunks', () => {
6-
const { next, isTurbopack } = nextTestSetup({
6+
const { next } = nextTestSetup({
77
files: __dirname,
88
skipDeployment: true,
99
})
1010

11-
;(isTurbopack ? it.skip : it)(
12-
'must not bundle any server modules into browser chunks',
13-
async () => {
14-
const sourcemaps = await next.readFiles(
15-
'.next/static/chunks',
16-
(filename) => filename.endsWith('.js.map')
17-
)
11+
let sources = []
12+
beforeAll(async () => {
13+
const sourcemaps = await next.readFiles('.next/static/chunks', (filename) =>
14+
filename.endsWith('.js.map')
15+
)
16+
17+
sources = sourcemaps.flatMap(
18+
(sourcemap) => (JSON.parse(sourcemap) as SourceMapPayload).sources
19+
)
20+
})
21+
it('must not bundle any server modules into browser chunks', () => {
22+
const serverSources = sources.filter(
23+
(source) =>
24+
/webpack:\/\/_N_E\/(\.\.\/)*src\/server\//.test(source) ||
25+
source.includes('next/dist/esm/server') ||
26+
source.includes('next/dist/server')
27+
)
1828

19-
const sources = sourcemaps.flatMap(
20-
(sourcemap) => (JSON.parse(sourcemap) as SourceMapPayload).sources
29+
if (serverSources.length > 0) {
30+
console.error(
31+
`Found the following server modules:\n ${serverSources.join('\n ')}\nIf any of these modules are allowed to be included in browser chunks, move them to src/shared or src/client.`
2132
)
2233

23-
const serverSources = sources.filter(
24-
(source) =>
25-
/webpack:\/\/_N_E\/(\.\.\/)*src\/server\//.test(source) ||
26-
source.includes('next/dist/esm/server') ||
27-
source.includes('next/dist/server')
34+
throw new Error('Did not expect any server modules in browser chunks.')
35+
}
36+
})
37+
38+
it('must not bundle any dev overlay into browser chunks', () => {
39+
const devOverlaySources = sources.filter((source) => {
40+
return (
41+
/webpack:\/\/_N_E\/(\.\.\/)*src\/client\/components\/react-dev-overlay\//.test(
42+
source
43+
) ||
44+
/next\/dist\/(esm\/)?client\/components\/react-dev-overlay/.test(source)
2845
)
46+
})
2947

30-
if (serverSources.length > 0) {
31-
console.error(
32-
`Found the following server modules:\n ${serverSources.join('\n ')}\nIf any of these modules are allowed to be included in browser chunks, move them to src/shared or src/client.`
33-
)
48+
if (devOverlaySources.length > 0) {
49+
const message = `Found the following dev overlay modules:\n ${devOverlaySources.join('\n')}`
50+
console.error(
51+
`${message}\nIf any of these modules are allowed to be included in production chunks, check the import and render conditions.`
52+
)
3453

35-
throw new Error('Did not expect any server modules in browser chunks.')
36-
}
54+
throw new Error(
55+
'Did not expect any dev overlay modules in browser chunks.\n' + message
56+
)
3757
}
38-
)
58+
})
3959
})

test/turbopack-build-tests-manifest.json

+10
Original file line numberDiff line numberDiff line change
@@ -18689,6 +18689,16 @@
1868918689
"flakey": [],
1869018690
"runtimeError": false
1869118691
},
18692+
"test/production/app-dir/browser-chunks/browser-chunks.test.ts": {
18693+
"passed": [],
18694+
"failed": [],
18695+
"pending": [
18696+
"browser-chunks must not bundle any server modules into browser chunks",
18697+
"browser-chunks must not bundle any dev overlay into browser chunks"
18698+
],
18699+
"flakey": [],
18700+
"runtimeError": false
18701+
},
1869218702
"test/production/typescript-basic/typechecking.test.ts": {
1869318703
"passed": ["typechecking should typecheck"],
1869418704
"failed": [],

0 commit comments

Comments
 (0)