Skip to content

Commit 476af24

Browse files
authored
Revert "Prefer module over main on main fields for app router server compiler" (#56766)
This was causing some issues with our deployments. [slack x-ref](https://vercel.slack.com/archives/C04DUD7EB1B/p1697146531305779)
1 parent 961fd01 commit 476af24

File tree

14 files changed

+47
-99
lines changed

14 files changed

+47
-99
lines changed

packages/next/src/build/handle-externals.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export async function resolveExternal(
4444
context: string,
4545
request: string,
4646
isEsmRequested: boolean,
47+
hasAppDir: boolean,
4748
getResolve: (
4849
options: any
4950
) => (
@@ -65,7 +66,11 @@ export async function resolveExternal(
6566

6667
let preferEsmOptions =
6768
esmExternals && isEsmRequested ? [true, false] : [false]
68-
69+
// Disable esm resolving for app/ and pages/ so for esm package using under pages/
70+
// won't load react through esm loader
71+
if (hasAppDir) {
72+
preferEsmOptions = [false]
73+
}
6974
for (const preferEsm of preferEsmOptions) {
7075
const resolve = getResolve(
7176
preferEsm ? esmResolveOptions : nodeResolveOptions
@@ -130,10 +135,12 @@ export function makeExternalHandler({
130135
config,
131136
optOutBundlingPackageRegex,
132137
dir,
138+
hasAppDir,
133139
}: {
134140
config: NextConfigComplete
135141
optOutBundlingPackageRegex: RegExp
136142
dir: string
143+
hasAppDir: boolean
137144
}) {
138145
let resolvedExternalPackageDirs: Map<string, string>
139146
const looseEsmExternals = config.experimental?.esmExternals === 'loose'
@@ -286,6 +293,7 @@ export function makeExternalHandler({
286293
context,
287294
request,
288295
isEsmRequested,
296+
hasAppDir,
289297
getResolve,
290298
isLocal ? resolveNextExternal : undefined
291299
)
@@ -345,6 +353,7 @@ export function makeExternalHandler({
345353
config.experimental.esmExternals,
346354
context,
347355
pkg + '/package.json',
356+
hasAppDir,
348357
isEsmRequested,
349358
getResolve,
350359
isLocal ? resolveNextExternal : undefined

packages/next/src/build/webpack-config-rules/resolve.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

packages/next/src/build/webpack-config.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ import { needsExperimentalReact } from '../lib/needs-experimental-react'
7474
import { getDefineEnvPlugin } from './webpack/plugins/define-env-plugin'
7575
import type { SWCLoaderOptions } from './webpack/loaders/next-swc-loader'
7676
import { isResourceInPackages, makeExternalHandler } from './handle-externals'
77-
import {
78-
getMainField,
79-
edgeConditionNames,
80-
} from './webpack-config-rules/resolve'
8177

8278
type ExcludesFalse = <T>(x: T | false) => x is T
8379
type ClientEntries = {
@@ -108,6 +104,21 @@ const babelIncludeRegexes: RegExp[] = [
108104
const asyncStoragesRegex =
109105
/next[\\/]dist[\\/](esm[\\/])?client[\\/]components[\\/](static-generation-async-storage|action-async-storage|request-async-storage)/
110106

107+
// exports.<conditionName>
108+
const edgeConditionNames = [
109+
'edge-light',
110+
'worker',
111+
// inherits the default conditions
112+
'...',
113+
]
114+
115+
// packageJson.<mainField>
116+
const mainFieldsPerCompiler: Record<CompilerNameValues, string[]> = {
117+
[COMPILER_NAMES.server]: ['main', 'module'],
118+
[COMPILER_NAMES.client]: ['browser', 'module', 'main'],
119+
[COMPILER_NAMES.edgeServer]: edgeConditionNames,
120+
}
121+
111122
// Support for NODE_PATH
112123
const nodePathList = (process.env.NODE_PATH || '')
113124
.split(process.platform === 'win32' ? ';' : ':')
@@ -920,8 +931,7 @@ export default async function getBaseWebpackConfig(
920931
},
921932
}
922933
: undefined),
923-
// default main fields use pages dir ones, and customize app router ones in loaders.
924-
mainFields: getMainField('pages', compilerType),
934+
mainFields: mainFieldsPerCompiler[compilerType],
925935
...(isEdgeServer && {
926936
conditionNames: edgeConditionNames,
927937
}),
@@ -1029,6 +1039,7 @@ export default async function getBaseWebpackConfig(
10291039
config,
10301040
optOutBundlingPackageRegex,
10311041
dir,
1042+
hasAppDir,
10321043
})
10331044

10341045
const shouldIncludeExternalDirs =
@@ -1599,7 +1610,6 @@ export default async function getBaseWebpackConfig(
15991610
],
16001611
},
16011612
resolve: {
1602-
mainFields: getMainField('app', compilerType),
16031613
conditionNames: reactServerCondition,
16041614
// If missing the alias override here, the default alias will be used which aliases
16051615
// react to the direct file path, not the package name. In that case the condition
@@ -1744,9 +1754,6 @@ export default async function getBaseWebpackConfig(
17441754
],
17451755
exclude: [codeCondition.exclude],
17461756
use: swcLoaderForClientLayer,
1747-
resolve: {
1748-
mainFields: getMainField('app', compilerType),
1749-
},
17501757
},
17511758
]
17521759
: []),

packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance {
743743
context,
744744
request,
745745
isEsmRequested,
746+
!!this.appDirEnabled,
746747
(options) => (_: string, resRequest: string) => {
747748
return getResolve(options)(parent, resRequest, job)
748749
},

test/e2e/app-dir/app-external/app-external.test.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,14 @@ createNextDescribe(
3939
buildCommand: 'yarn build',
4040
skipDeployment: true,
4141
},
42-
({ next }) => {
42+
({ next, isNextDev }) => {
4343
it('should be able to opt-out 3rd party packages being bundled in server components', async () => {
4444
await next.fetch('/react-server/optout').then(async (response) => {
4545
const result = await resolveStreamResponse(response)
4646
expect(result).toContain('Server: index.default')
4747
expect(result).toContain('Server subpath: subpath.default')
4848
expect(result).toContain('Client: index.default')
4949
expect(result).toContain('Client subpath: subpath.default')
50-
expect(result).toContain('opt-out-react-version: 18.2.0')
5150
})
5251
})
5352

@@ -92,23 +91,24 @@ createNextDescribe(
9291
})
9392

9493
it('should resolve 3rd party package exports based on the react-server condition', async () => {
95-
const $ = await next.render$('/react-server/3rd-party-package')
96-
97-
const result = $('body').text()
98-
99-
// Package should be resolved based on the react-server condition,
100-
// as well as package's internal & external dependencies.
101-
expect(result).toContain(
102-
'Server: index.react-server:react.subset:dep.server'
103-
)
104-
expect(result).toContain('Client: index.default:react.full:dep.default')
105-
106-
// Subpath exports should be resolved based on the condition too.
107-
expect(result).toContain('Server subpath: subpath.react-server')
108-
expect(result).toContain('Client subpath: subpath.default')
109-
110-
// Prefer `module` field for isomorphic packages.
111-
expect($('#main-field').text()).toContain('server-module-field:module')
94+
await next
95+
.fetch('/react-server/3rd-party-package')
96+
.then(async (response) => {
97+
const result = await resolveStreamResponse(response)
98+
99+
// Package should be resolved based on the react-server condition,
100+
// as well as package's internal & external dependencies.
101+
expect(result).toContain(
102+
'Server: index.react-server:react.subset:dep.server'
103+
)
104+
expect(result).toContain(
105+
'Client: index.default:react.full:dep.default'
106+
)
107+
108+
// Subpath exports should be resolved based on the condition too.
109+
expect(result).toContain('Server subpath: subpath.react-server')
110+
expect(result).toContain('Client subpath: subpath.default')
111+
})
112112
})
113113

114114
it('should correctly collect global css imports and mark them as side effects', async () => {

test/e2e/app-dir/app-external/app/react-server/3rd-party-package/page.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import v from 'conditional-exports'
22
import v1 from 'conditional-exports/subpath'
3-
import { name as serverFieldName } from 'server-module-field'
43

54
import Client from './client'
65

@@ -12,8 +11,6 @@ export default function Page() {
1211
{`Server subpath: ${v1}`}
1312
<br />
1413
<Client />
15-
<br />
16-
<div id="main-field">{`Server module field: ${serverFieldName}`}</div>
1714
</div>
1815
)
1916
}
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import v from 'conditional-exports-optout'
22
import v1 from 'conditional-exports-optout/subpath'
3-
import { getReactVersion } from 'conditional-exports-optout/react'
43

54
import Client from './client'
65

@@ -12,9 +11,6 @@ export default function Page() {
1211
{`Server subpath: ${v1}`}
1312
<br />
1413
<Client />
15-
<p id="optout-react-version">
16-
{`opt-out-react-version: ${getReactVersion()}`}
17-
</p>
1814
</div>
1915
)
2016
}

test/e2e/app-dir/app-external/node_modules_bak/conditional-exports-optout/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
"react-server": "./subpath.server.js",
1111
"default": "./subpath.js"
1212
},
13-
"./react": {
14-
"import": "./react.js"
15-
},
1613
"./package.json": "./package.json"
1714
}
1815
}

test/e2e/app-dir/app-external/node_modules_bak/conditional-exports-optout/react.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/e2e/app-dir/app-external/node_modules_bak/conditional-exports/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
"react-server": "./subpath.server.js",
1717
"default": "./subpath.js"
1818
},
19-
"./react": {
20-
"import": "./react.js"
21-
},
2219
"./package.json": "./package.json"
2320
}
2421
}

test/e2e/app-dir/app-external/node_modules_bak/conditional-exports/react.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/e2e/app-dir/app-external/node_modules_bak/server-module-field/index.cjs

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/e2e/app-dir/app-external/node_modules_bak/server-module-field/index.esm.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/e2e/app-dir/app-external/node_modules_bak/server-module-field/package.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)