fix: babel usage with next/image (#61835)

### Why

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

### What

- Fixes https://github.com/vercel/next.js/issues/61116

Closes NEXT-2410
Closes NEXT-2328

---------

Co-authored-by: Jiachi Liu <inbox@huozhi.im>
This commit is contained in:
Steven 2024-02-08 18:16:30 -05:00 committed by GitHub
parent 2ca8d3d3cc
commit 698fcbb8d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 72 additions and 11 deletions

View file

@ -260,7 +260,7 @@
"p-limit": "3.1.0",
"path-browserify": "1.0.1",
"path-to-regexp": "6.1.0",
"picomatch": "3.0.1",
"picomatch": "4.0.1",
"platform": "1.3.6",
"postcss-flexbugs-fixes": "5.0.2",
"postcss-modules-extract-imports": "3.0.0",

View file

@ -110,8 +110,16 @@ const babelIncludeRegexes: RegExp[] = [
/[\\/](strip-ansi|ansi-regex|styled-jsx)[\\/]/,
]
const preCompileReactRegex =
/next[\\/]dist[\\/]compiled[\\/](react|react-dom|react-server-dom-webpack)(-experimental)?($|[\\/])/
const browserNonTranspileModules = [
// Transpiling `process/browser` will trigger babel compilation error due to value replacement.
// TypeError: Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "BooleanLiteral"
// e.g. `process.browser = true` will become `true = true`.
/[\\/]node_modules[\\/]process[\\/]browser/,
// Exclude precompiled react packages from browser compilation due to SWC helper insertion (#61791),
// We fixed the issue but it's safer to exclude them from compilation since they don't need to be re-compiled.
/[\\/]next[\\/]dist[\\/]compiled[\\/](react|react-dom|react-server-dom-webpack)(-experimental)?($|[\\/])/,
]
const precompileRegex = /[\\/]next[\\/]dist[\\/]compiled[\\/]/
const asyncStoragesRegex =
/next[\\/]dist[\\/](esm[\\/])?client[\\/]components[\\/](static-generation-async-storage|action-async-storage|request-async-storage)/
@ -1423,7 +1431,12 @@ export default async function getBaseWebpackConfig(
? [
{
test: codeCondition.test,
exclude: [codeCondition.exclude, transpilePackagesRegex],
exclude: [
// exclude unchanged modules from react-refresh
codeCondition.exclude,
transpilePackagesRegex,
precompileRegex,
],
issuerLayer: WEBPACK_LAYERS.appPagesBrowser,
use: reactRefreshLoaders,
resolve: {
@ -1471,7 +1484,8 @@ export default async function getBaseWebpackConfig(
{
test: codeCondition.test,
issuerLayer: WEBPACK_LAYERS.appPagesBrowser,
exclude: preCompileReactRegex,
// Exclude the transpilation of the app layer due to compilation issues
exclude: browserNonTranspileModules,
use: appBrowserLayerLoaders,
resolve: {
mainFields: getMainField(compilerType, true),

File diff suppressed because one or more lines are too long

View file

@ -1278,8 +1278,8 @@ importers:
specifier: 6.1.0
version: 6.1.0
picomatch:
specifier: 3.0.1
version: 3.0.1
specifier: 4.0.1
version: 4.0.1
platform:
specifier: 1.3.6
version: 1.3.6
@ -19347,9 +19347,9 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
/picomatch@3.0.1:
resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==}
engines: {node: '>=10'}
/picomatch@4.0.1:
resolution: {integrity: sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==}
engines: {node: '>=12'}
dev: true
/pidtree@0.3.0:

View file

@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": []
}

View file

@ -0,0 +1,12 @@
export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}

View file

@ -0,0 +1,12 @@
import Image from 'next/image'
export default function Home() {
return (
<Image
alt="red square"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg=="
width={64}
height={64}
/>
)
}

View file

@ -0,0 +1,19 @@
/* eslint-env jest */
import { fetchViaHTTP, findPort, killApp, launchApp } from 'next-test-utils'
;(process.env.TURBOPACK ? describe.skip : describe)('babel-next-image', () => {
let appPort
let app
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(__dirname, appPort)
})
afterAll(() => killApp(app))
it('should work with babel and next/image', async () => {
const res = await fetchViaHTTP(appPort, '/')
expect(res.status).toBe(200)
})
})