From c3b4d8bba4b7f6c2e88e047dbadd8a775c187b10 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 14 Feb 2024 14:22:25 +0100 Subject: [PATCH 1/6] Fix extra swc optimizer applied to node_modules in browser layer --- packages/next/src/build/swc/options.ts | 3 +++ .../app-dir/app-external/app-external.test.ts | 15 ++++++++++++- .../app-dir/app-external/app/browser/page.js | 22 +++++++++++++++++++ .../app-external/app/browser/worker.js | 3 +++ .../browser-module/browser.js | 4 ++++ .../node_modules_bak/browser-module/index.js | 1 + .../browser-module/package.json | 7 ++++++ 7 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/app-external/app/browser/page.js create mode 100644 test/e2e/app-dir/app-external/app/browser/worker.js create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/browser-module/browser.js create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/browser-module/index.js create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/browser-module/package.json diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index d81375778e019..43cabc4f9c7c7 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -482,6 +482,9 @@ export function getLoaderSWCOptions({ options.isPageFile = false options.optimizeServerReact = undefined options.cjsRequireOptimizer = undefined + // Disable optimizer for node_modules in app browser layer, to avoid unnecessary replacement. + // e.g. typeof window could result differently in js worker or browser. + options.jsc.transform.optimizer = null } return options 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 91c95ba2285b9..44576abcef0bc 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, hasRedbox, shouldRunTurboDevTest } from 'next-test-utils' +import { check, hasRedbox, retry, shouldRunTurboDevTest } from 'next-test-utils' async function resolveStreamResponse(response: any, onData?: any) { let result = '' @@ -153,6 +153,19 @@ createNextDescribe( ).toMatch(/^__myFont_.{6}, __myFont_Fallback_.{6}$/) }) + it('should not apply swc optimizer transform for external packages in browser layer', async () => { + const browser = await next.browser('/browser') + expect(await browser.elementByCss('#worker-state').text()).toBe('default') + + await browser.elementByCss('button').click() + + await retry(async () => { + expect(await browser.elementByCss('#worker-state').text()).toBe( + 'worker.js:browser-module/other' + ) + }) + }) + describe('react in external esm packages', () => { it('should use the same react in client app', async () => { const html = await next.render('/esm/client') diff --git a/test/e2e/app-dir/app-external/app/browser/page.js b/test/e2e/app-dir/app-external/app/browser/page.js new file mode 100644 index 0000000000000..5fa1381c6df57 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/browser/page.js @@ -0,0 +1,22 @@ +'use client' +import { useState } from 'react' + +export default function Home() { + const [state, setState] = useState('default') + return ( +
+ +

Worker state:

+

{state}

+
+ ) +} diff --git a/test/e2e/app-dir/app-external/app/browser/worker.js b/test/e2e/app-dir/app-external/app/browser/worker.js new file mode 100644 index 0000000000000..503cc8e702450 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/browser/worker.js @@ -0,0 +1,3 @@ +import { value } from 'browser-module' + +self.postMessage('worker.js:' + value) diff --git a/test/e2e/app-dir/app-external/node_modules_bak/browser-module/browser.js b/test/e2e/app-dir/app-external/node_modules_bak/browser-module/browser.js new file mode 100644 index 0000000000000..60215f6777c41 --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/browser-module/browser.js @@ -0,0 +1,4 @@ +'use client' + +export const value = + 'browser-module/' + (typeof window !== 'undefined' ? 'browser' : 'other') diff --git a/test/e2e/app-dir/app-external/node_modules_bak/browser-module/index.js b/test/e2e/app-dir/app-external/node_modules_bak/browser-module/index.js new file mode 100644 index 0000000000000..35b818f5f076e --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/browser-module/index.js @@ -0,0 +1 @@ +export const value = 'browser-module/index' diff --git a/test/e2e/app-dir/app-external/node_modules_bak/browser-module/package.json b/test/e2e/app-dir/app-external/node_modules_bak/browser-module/package.json new file mode 100644 index 0000000000000..fbfb874e865ce --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/browser-module/package.json @@ -0,0 +1,7 @@ +{ + "type": "module", + "exports": { + "browser": "./browser.js", + "default": "./index.js" + } +} From 014a8b52db76946d69a8708cadb3fcbfb267b3e0 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 14 Feb 2024 19:06:37 +0100 Subject: [PATCH 2/6] only disable globals --- packages/next/src/build/swc/options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index 43cabc4f9c7c7..45247e6cf76d1 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -484,7 +484,7 @@ export function getLoaderSWCOptions({ options.cjsRequireOptimizer = undefined // Disable optimizer for node_modules in app browser layer, to avoid unnecessary replacement. // e.g. typeof window could result differently in js worker or browser. - options.jsc.transform.optimizer = null + options.jsc.transform.optimizer.globals = null } return options From 41f8064a53c0d473eedd938e40cf1ccf27cd5fc8 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 14 Feb 2024 19:15:28 +0100 Subject: [PATCH 3/6] add into manifest --- test/turbopack-tests-manifest.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 67b588339fcbe..eb5bb2052743f 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -2567,7 +2567,8 @@ ], "failed": [ "app dir - external dependency server actions should compile server actions from node_modules in client components", - "app dir - external dependency should be able to opt-out 3rd party packages being bundled in server components" + "app dir - external dependency should be able to opt-out 3rd party packages being bundled in server components", + "app dir - external dependency should not apply swc optimizer transform for external packages in browser layer" ], "pending": [], "flakey": [], From 7d068db2e903cc42d0cb29b7b862d70d43918da2 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 14 Feb 2024 19:26:15 +0100 Subject: [PATCH 4/6] only disable window --- packages/next/src/build/swc/options.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index 45247e6cf76d1..dcabeee4c0a4e 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -484,7 +484,10 @@ export function getLoaderSWCOptions({ options.cjsRequireOptimizer = undefined // Disable optimizer for node_modules in app browser layer, to avoid unnecessary replacement. // e.g. typeof window could result differently in js worker or browser. - options.jsc.transform.optimizer.globals = null + // override for non-jest mode + if (options.jsc.transform.optimizer.globals) { + delete options.jsc.transform.optimizer.globals.typeofs.window + } } return options From 6507516c163a8670c30639bb3d7870c4808b2fcd Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 14 Feb 2024 20:59:21 +0100 Subject: [PATCH 5/6] safe check --- packages/next/src/build/swc/options.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index dcabeee4c0a4e..60e66fd2e0264 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -484,8 +484,7 @@ export function getLoaderSWCOptions({ options.cjsRequireOptimizer = undefined // Disable optimizer for node_modules in app browser layer, to avoid unnecessary replacement. // e.g. typeof window could result differently in js worker or browser. - // override for non-jest mode - if (options.jsc.transform.optimizer.globals) { + if (options.jsc.transform.optimizer.globals?.typesof) { delete options.jsc.transform.optimizer.globals.typeofs.window } } From bd96d5a4cd2a7cec21fb712cbb25cab92eecb2ea Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 14 Feb 2024 21:27:09 +0100 Subject: [PATCH 6/6] fix typo --- packages/next/src/build/swc/options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index 60e66fd2e0264..2751efbdec3e2 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -484,7 +484,7 @@ export function getLoaderSWCOptions({ options.cjsRequireOptimizer = undefined // Disable optimizer for node_modules in app browser layer, to avoid unnecessary replacement. // e.g. typeof window could result differently in js worker or browser. - if (options.jsc.transform.optimizer.globals?.typesof) { + if (options.jsc.transform.optimizer.globals?.typeofs) { delete options.jsc.transform.optimizer.globals.typeofs.window } }