diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 497258afa0af4..4c0b906cc50cb 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -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)/ @@ -1400,7 +1408,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: { @@ -1443,7 +1456,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), diff --git a/test/integration/babel-next-image/.babelrc b/test/integration/babel-next-image/.babelrc new file mode 100644 index 0000000000000..9fcef0394fdf0 --- /dev/null +++ b/test/integration/babel-next-image/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["next/babel"], + "plugins": [] +} diff --git a/test/integration/babel-next-image/app/layout.js b/test/integration/babel-next-image/app/layout.js new file mode 100644 index 0000000000000..8525f5f8c0b2a --- /dev/null +++ b/test/integration/babel-next-image/app/layout.js @@ -0,0 +1,12 @@ +export const metadata = { + title: 'Next.js', + description: 'Generated by Next.js', +} + +export default function RootLayout({ children }) { + return ( + + {children} + + ) +} diff --git a/test/integration/babel-next-image/app/page.js b/test/integration/babel-next-image/app/page.js new file mode 100644 index 0000000000000..4aa4e6613b0f2 --- /dev/null +++ b/test/integration/babel-next-image/app/page.js @@ -0,0 +1,12 @@ +import Image from 'next/image' + +export default function Home() { + return ( + red square + ) +} diff --git a/test/integration/babel-next-image/babel-next-image.test.js b/test/integration/babel-next-image/babel-next-image.test.js new file mode 100644 index 0000000000000..e9afa0e0b0776 --- /dev/null +++ b/test/integration/babel-next-image/babel-next-image.test.js @@ -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) + }) +})