Skip to content

Commit 7dbf6f8

Browse files
styflehuozhi
andcommitted
fix: babel usage with next/image (#61835)
The `process/browser` lib was imported and being transformed, but `process.browser = true` turns to `true = true` that causes the compilation error, we need to exclude them from certain compilation layers - Fixes #61116 Closes NEXT-2410 Closes NEXT-2328 --------- Co-authored-by: Jiachi Liu <[email protected]>
1 parent 3efc842 commit 7dbf6f8

File tree

5 files changed

+65
-4
lines changed

5 files changed

+65
-4
lines changed

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,16 @@ const babelIncludeRegexes: RegExp[] = [
110110
/[\\/](strip-ansi|ansi-regex|styled-jsx)[\\/]/,
111111
]
112112

113-
const preCompileReactRegex =
114-
/next[\\/]dist[\\/]compiled[\\/](react|react-dom|react-server-dom-webpack)(-experimental)?($|[\\/])/
113+
const browserNonTranspileModules = [
114+
// Transpiling `process/browser` will trigger babel compilation error due to value replacement.
115+
// TypeError: Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "BooleanLiteral"
116+
// e.g. `process.browser = true` will become `true = true`.
117+
/[\\/]node_modules[\\/]process[\\/]browser/,
118+
// Exclude precompiled react packages from browser compilation due to SWC helper insertion (#61791),
119+
// We fixed the issue but it's safer to exclude them from compilation since they don't need to be re-compiled.
120+
/[\\/]next[\\/]dist[\\/]compiled[\\/](react|react-dom|react-server-dom-webpack)(-experimental)?($|[\\/])/,
121+
]
122+
const precompileRegex = /[\\/]next[\\/]dist[\\/]compiled[\\/]/
115123

116124
const asyncStoragesRegex =
117125
/next[\\/]dist[\\/](esm[\\/])?client[\\/]components[\\/](static-generation-async-storage|action-async-storage|request-async-storage)/
@@ -1400,7 +1408,12 @@ export default async function getBaseWebpackConfig(
14001408
? [
14011409
{
14021410
test: codeCondition.test,
1403-
exclude: [codeCondition.exclude, transpilePackagesRegex],
1411+
exclude: [
1412+
// exclude unchanged modules from react-refresh
1413+
codeCondition.exclude,
1414+
transpilePackagesRegex,
1415+
precompileRegex,
1416+
],
14041417
issuerLayer: WEBPACK_LAYERS.appPagesBrowser,
14051418
use: reactRefreshLoaders,
14061419
resolve: {
@@ -1443,7 +1456,8 @@ export default async function getBaseWebpackConfig(
14431456
{
14441457
test: codeCondition.test,
14451458
issuerLayer: WEBPACK_LAYERS.appPagesBrowser,
1446-
exclude: preCompileReactRegex,
1459+
// Exclude the transpilation of the app layer due to compilation issues
1460+
exclude: browserNonTranspileModules,
14471461
use: appBrowserLayerLoaders,
14481462
resolve: {
14491463
mainFields: getMainField(compilerType, true),
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"presets": ["next/babel"],
3+
"plugins": []
4+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const metadata = {
2+
title: 'Next.js',
3+
description: 'Generated by Next.js',
4+
}
5+
6+
export default function RootLayout({ children }) {
7+
return (
8+
<html lang="en">
9+
<body>{children}</body>
10+
</html>
11+
)
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Image from 'next/image'
2+
3+
export default function Home() {
4+
return (
5+
<Image
6+
alt="red square"
7+
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg=="
8+
width={64}
9+
height={64}
10+
/>
11+
)
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* eslint-env jest */
2+
3+
import { fetchViaHTTP, findPort, killApp, launchApp } from 'next-test-utils'
4+
;(process.env.TURBOPACK ? describe.skip : describe)('babel-next-image', () => {
5+
let appPort
6+
let app
7+
8+
beforeAll(async () => {
9+
appPort = await findPort()
10+
app = await launchApp(__dirname, appPort)
11+
})
12+
13+
afterAll(() => killApp(app))
14+
15+
it('should work with babel and next/image', async () => {
16+
const res = await fetchViaHTTP(appPort, '/')
17+
expect(res.status).toBe(200)
18+
})
19+
})

0 commit comments

Comments
 (0)