From 3738e8ecc04f2cc3f24dcf468ad315c060b9e5ca Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 12 Jan 2024 21:44:41 +0100 Subject: [PATCH] Fix react-refresh for transpiled packages (#60563) ### What We're applying react-refresh to browser layer and inject ESM or CJS helper based on file type. Some package from `trasnpilePackages` might contain CJS browser bundle. And injecting ESM helper breaks them. Actually they don't need to have fast refresh ability since they're in `node_modules`. ### How Skip react-refresh for transpiled packages as they're in node_modules and won't change. Fixes #56487 Closes NEXT-2061 --- packages/next/src/build/webpack-config.ts | 8 +++++++- test/e2e/app-dir/app-external/app-external.test.ts | 6 +++++- test/e2e/app-dir/app-external/app/cjs/client/page.js | 2 ++ .../app-external/app/external-imports/client/page.js | 2 +- test/e2e/app-dir/app-external/next.config.js | 2 +- .../node_modules_bak/transpile-cjs-lib/index.js | 1 + .../node_modules_bak/transpile-cjs-lib/package.json | 5 +++++ .../{untranspiled-module => transpile-ts-lib}/index.ts | 0 .../node_modules_bak/transpile-ts-lib/package.json | 4 ++++ .../node_modules_bak/untranspiled-module/package.json | 4 ---- 10 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/index.js create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/package.json rename test/e2e/app-dir/app-external/node_modules_bak/{untranspiled-module => transpile-ts-lib}/index.ts (100%) create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/transpile-ts-lib/package.json delete mode 100644 test/e2e/app-dir/app-external/node_modules_bak/untranspiled-module/package.json diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 57f14bdbb0ee3..babf77f95786d 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -781,6 +781,12 @@ export default async function getBaseWebpackConfig( .join('|')})[/\\\\]` ) + const transpilePackagesRegex = new RegExp( + `[/\\\\]node_modules[/\\\\](${config.transpilePackages + ?.map((p) => p.replace(/\//g, '[/\\\\]')) + .join('|')})[/\\\\]` + ) + const handleExternals = makeExternalHandler({ config, optOutBundlingPackages, @@ -1398,7 +1404,7 @@ export default async function getBaseWebpackConfig( ? [ { test: codeCondition.test, - exclude: codeCondition.exclude, + exclude: [codeCondition.exclude, transpilePackagesRegex], issuerLayer: WEBPACK_LAYERS.appPagesBrowser, use: reactRefreshLoaders, resolve: { diff --git a/test/e2e/app-dir/app-external/app-external.test.ts b/test/e2e/app-dir/app-external/app-external.test.ts index 479e8f2fba71b..91539a5e6ce3d 100644 --- a/test/e2e/app-dir/app-external/app-external.test.ts +++ b/test/e2e/app-dir/app-external/app-external.test.ts @@ -1,5 +1,5 @@ import { createNextDescribe } from 'e2e-utils' -import { check, shouldRunTurboDevTest } from 'next-test-utils' +import { check, hasRedbox, shouldRunTurboDevTest } from 'next-test-utils' async function resolveStreamResponse(response: any, onData?: any) { let result = '' @@ -229,6 +229,10 @@ createNextDescribe( it('should emit cjs helpers for external cjs modules when compiled', async () => { const $ = await next.render$('/cjs/client') expect($('#private-prop').text()).toBe('prop') + expect($('#transpile-cjs-lib').text()).toBe('transpile-cjs-lib') + + const browser = await next.browser('/cjs/client') + expect(await hasRedbox(browser)).toBe(false) }) it('should export client module references in esm', async () => { diff --git a/test/e2e/app-dir/app-external/app/cjs/client/page.js b/test/e2e/app-dir/app-external/app/cjs/client/page.js index 4cac50381034b..7f447d6adf7a8 100644 --- a/test/e2e/app-dir/app-external/app/cjs/client/page.js +++ b/test/e2e/app-dir/app-external/app/cjs/client/page.js @@ -1,11 +1,13 @@ 'use client' import { instance } from 'cjs-modern-syntax' +import { packageName } from 'transpile-cjs-lib' export default function Page() { return ( <>
{instance.getProp()}
+
{packageName}
) } diff --git a/test/e2e/app-dir/app-external/app/external-imports/client/page.js b/test/e2e/app-dir/app-external/app/external-imports/client/page.js index 183053587e181..1634c20f8a2ce 100644 --- a/test/e2e/app-dir/app-external/app/external-imports/client/page.js +++ b/test/e2e/app-dir/app-external/app/external-imports/client/page.js @@ -2,7 +2,7 @@ import getType, { named, value, array, obj } from 'non-isomorphic-text' -import add from 'untranspiled-module' +import add from 'transpile-ts-lib' // ESM externals has react has a peer dependency import useSWR from 'swr' diff --git a/test/e2e/app-dir/app-external/next.config.js b/test/e2e/app-dir/app-external/next.config.js index 4b1cb6524d198..8ea72b2909c2f 100644 --- a/test/e2e/app-dir/app-external/next.config.js +++ b/test/e2e/app-dir/app-external/next.config.js @@ -1,6 +1,6 @@ module.exports = { reactStrictMode: true, - transpilePackages: ['untranspiled-module', 'css', 'font'], + transpilePackages: ['css', 'font', 'transpile-ts-lib', 'transpile-cjs-lib'], experimental: { serverComponentsExternalPackages: [ 'conditional-exports-optout', diff --git a/test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/index.js b/test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/index.js new file mode 100644 index 0000000000000..f6299fd40fb02 --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/index.js @@ -0,0 +1 @@ +exports.packageName = 'transpile-cjs-lib' diff --git a/test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/package.json b/test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/package.json new file mode 100644 index 0000000000000..797dfef9dbae7 --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/transpile-cjs-lib/package.json @@ -0,0 +1,5 @@ +{ + "name": "transpile-cjs-lib", + "type": "commonjs", + "exports": "./index.js" +} diff --git a/test/e2e/app-dir/app-external/node_modules_bak/untranspiled-module/index.ts b/test/e2e/app-dir/app-external/node_modules_bak/transpile-ts-lib/index.ts similarity index 100% rename from test/e2e/app-dir/app-external/node_modules_bak/untranspiled-module/index.ts rename to test/e2e/app-dir/app-external/node_modules_bak/transpile-ts-lib/index.ts diff --git a/test/e2e/app-dir/app-external/node_modules_bak/transpile-ts-lib/package.json b/test/e2e/app-dir/app-external/node_modules_bak/transpile-ts-lib/package.json new file mode 100644 index 0000000000000..10f78610dabf1 --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/transpile-ts-lib/package.json @@ -0,0 +1,4 @@ +{ + "name": "transpile-ts-lib", + "main": "index.ts" +} diff --git a/test/e2e/app-dir/app-external/node_modules_bak/untranspiled-module/package.json b/test/e2e/app-dir/app-external/node_modules_bak/untranspiled-module/package.json deleted file mode 100644 index 05558992ba58e..0000000000000 --- a/test/e2e/app-dir/app-external/node_modules_bak/untranspiled-module/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "untranspiled-module", - "main": "index.ts" -}