From 8f96326a729fd51bc52c3491554fd080222e0b79 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 17 Jun 2021 12:50:56 +0200 Subject: [PATCH 01/11] Add runtime to hotUpdateMainFilename --- packages/next/build/webpack-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 5c18d1c55518d..b175ab5682a5e 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -933,7 +933,7 @@ export default async function getBaseWebpackConfig( ? 'static/webpack/[id].[fullhash].hot-update.js' : 'static/webpack/[id].[hash].hot-update.js', hotUpdateMainFilename: isWebpack5 - ? 'static/webpack/[fullhash].hot-update.json' + ? 'static/webpack/[fullhash].[runtime].hot-update.json' : 'static/webpack/[hash].hot-update.json', // This saves chunks with the name given via `import()` chunkFilename: isServer From 3e08d5ae6acb25c1116e64784dc9362efd63fd6e Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 17 Jun 2021 12:58:51 +0200 Subject: [PATCH 02/11] Set splitChunks option to false --- packages/next/build/webpack-config.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index b175ab5682a5e..5a95054b08668 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -484,14 +484,9 @@ export default async function getBaseWebpackConfig( // Contains various versions of the Webpack SplitChunksPlugin used in different build types const splitChunksConfigs: { - [propName: string]: webpack.Options.SplitChunksOptions + [propName: string]: webpack.Options.SplitChunksOptions | false } = { - dev: { - cacheGroups: { - default: false, - vendors: false, - }, - }, + dev: false, prodGranular: { // Keep main and _app chunks unsplitted in webpack 5 // as we don't need a separate vendor chunk from that @@ -585,7 +580,7 @@ export default async function getBaseWebpackConfig( } // Select appropriate SplitChunksPlugin config for this build - let splitChunksConfig: webpack.Options.SplitChunksOptions + let splitChunksConfig: webpack.Options.SplitChunksOptions | false if (dev) { splitChunksConfig = splitChunksConfigs.dev } else { From b6acdf86f14f85996e4c19cc8343449040cb4763 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 17 Jun 2021 13:57:08 +0200 Subject: [PATCH 03/11] Add test for worker --- package.json | 1 + .../worker-webpack5/lib/sharedCode.js | 17 ++++++ .../integration/worker-webpack5/lib/worker.js | 8 +++ .../worker-webpack5/next.config.js | 1 + .../worker-webpack5/pages/index.js | 38 ++++++++++++ .../worker-webpack5/test/index.test.js | 58 +++++++++++++++++++ yarn.lock | 5 ++ 7 files changed, 128 insertions(+) create mode 100644 test/integration/worker-webpack5/lib/sharedCode.js create mode 100644 test/integration/worker-webpack5/lib/worker.js create mode 100644 test/integration/worker-webpack5/next.config.js create mode 100644 test/integration/worker-webpack5/pages/index.js create mode 100644 test/integration/worker-webpack5/test/index.test.js diff --git a/package.json b/package.json index b3ac6631f0316..48543513df2bb 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "eslint-plugin-react-hooks": "4.2.0", "execa": "2.0.3", "express": "4.17.0", + "faker": "5.5.3", "faunadb": "2.6.1", "firebase": "7.14.5", "fs-extra": "9.0.0", diff --git a/test/integration/worker-webpack5/lib/sharedCode.js b/test/integration/worker-webpack5/lib/sharedCode.js new file mode 100644 index 0000000000000..da7cd7ab6dd3d --- /dev/null +++ b/test/integration/worker-webpack5/lib/sharedCode.js @@ -0,0 +1,17 @@ +export function Expensive() { + const start = performance.now() + let i = 99999 + + const bigArray = [] + while (--i) { + bigArray.push(i) + } + + const endTime = performance.now() + + if (typeof window === 'undefined') { + console.log('[WORKER] Completed expensive function in', endTime - start) + } else { + console.log('[WEB] Completed expensive function in', endTime - start) + } +} diff --git a/test/integration/worker-webpack5/lib/worker.js b/test/integration/worker-webpack5/lib/worker.js new file mode 100644 index 0000000000000..d34bcedd68d23 --- /dev/null +++ b/test/integration/worker-webpack5/lib/worker.js @@ -0,0 +1,8 @@ +import { Expensive } from './sharedCode' +import faker from 'faker' + +// Ensure a large libraries is added so that splitChunks would trigger if enabled. +console.log(faker) + +Expensive() +self.postMessage(true) diff --git a/test/integration/worker-webpack5/next.config.js b/test/integration/worker-webpack5/next.config.js new file mode 100644 index 0000000000000..4ba52ba2c8df6 --- /dev/null +++ b/test/integration/worker-webpack5/next.config.js @@ -0,0 +1 @@ +module.exports = {} diff --git a/test/integration/worker-webpack5/pages/index.js b/test/integration/worker-webpack5/pages/index.js new file mode 100644 index 0000000000000..61a7c70a03c09 --- /dev/null +++ b/test/integration/worker-webpack5/pages/index.js @@ -0,0 +1,38 @@ +import * as React from 'react' +import { Expensive } from '../lib/sharedCode' + +export default function Home() { + const [expensiveWebStatus, setExpensiveWebStatus] = React.useState('WAIT') + const [expensiveWorkerStatus, setExpensiveWorkerComplete] = React.useState( + 'WAIT' + ) + const worker = React.useRef() + + React.useEffect(() => { + worker.current = new Worker(new URL('../lib/worker.js', import.meta.url)) + worker.current.addEventListener('message', ({ data }) => { + if (data) { + setExpensiveWorkerComplete('PASS') + } + }) + worker.current.addEventListener('error', (data) => { + setExpensiveWorkerComplete('FAIL') + }) + }, [worker, setExpensiveWorkerComplete]) + React.useEffect(() => { + try { + Expensive() + setExpensiveWebStatus('PASS') + } catch { + setExpensiveWebStatus('FAIL') + } + }, []) + + return ( +
+

$RefreshRegistry repro

+
Web: {expensiveWebStatus}
+
Worker: {expensiveWorkerStatus}
+
+ ) +} diff --git a/test/integration/worker-webpack5/test/index.test.js b/test/integration/worker-webpack5/test/index.test.js new file mode 100644 index 0000000000000..70d410cc6d602 --- /dev/null +++ b/test/integration/worker-webpack5/test/index.test.js @@ -0,0 +1,58 @@ +/* eslint-env jest */ +import { + check, + findPort, + killApp, + launchApp, + nextStart, + nextBuild, +} from 'next-test-utils' +import webdriver from 'next-webdriver' +import { join } from 'path' + +const appDir = join(__dirname, '../') + +jest.setTimeout(1000 * 60 * 2) + +let appPort +let app + +const runTests = () => { + it('should pass on both client and worker', async () => { + let browser + try { + browser = await webdriver(appPort, '/') + await browser.waitForElementByCss('#web-status') + await check(() => browser.elementByCss('#web-status').text(), /PASS/i) + await browser.waitForElementByCss('#worker-status') + await check(() => browser.elementByCss('#worker-status').text(), /PASS/i) + } finally { + if (browser) { + await browser.close() + } + } + }) +} + +describe('Web Workers with webpack 5', () => { + describe('dev mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) + + describe('server mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) +}) diff --git a/yarn.lock b/yarn.lock index fa2aa90034633..5fcf61ea04d1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7494,6 +7494,11 @@ extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" +faker@5.5.3: + version "5.5.3" + resolved "https://registry.yarnpkg.com/faker/-/faker-5.5.3.tgz#c57974ee484431b25205c2c8dc09fda861e51e0e" + integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g== + fast-deep-equal@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" From 31aeb4c38904026e0c975e363b5b939edc52942b Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 17 Jun 2021 14:04:06 +0200 Subject: [PATCH 04/11] Only set to false for webpack5 --- packages/next/build/webpack-config.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 5a95054b08668..c41a04b8c1767 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -486,7 +486,12 @@ export default async function getBaseWebpackConfig( const splitChunksConfigs: { [propName: string]: webpack.Options.SplitChunksOptions | false } = { - dev: false, + dev: { + cacheGroups: { + default: false, + vendors: false, + }, + }, prodGranular: { // Keep main and _app chunks unsplitted in webpack 5 // as we don't need a separate vendor chunk from that @@ -582,7 +587,7 @@ export default async function getBaseWebpackConfig( // Select appropriate SplitChunksPlugin config for this build let splitChunksConfig: webpack.Options.SplitChunksOptions | false if (dev) { - splitChunksConfig = splitChunksConfigs.dev + splitChunksConfig = isWebpack5 ? false : splitChunksConfigs.dev } else { splitChunksConfig = splitChunksConfigs.prodGranular } From a5249e6ce4417ac0117c9b9c310dc4cc5ee34d46 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 17 Jun 2021 14:47:41 +0200 Subject: [PATCH 05/11] Set publicPath during build --- packages/next/build/webpack-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index c41a04b8c1767..1c5f96f7aebc2 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -914,7 +914,7 @@ export default async function getBaseWebpackConfig( : {}), // we must set publicPath to an empty value to override the default of // auto which doesn't work in IE11 - publicPath: '', + publicPath: `${config.assetPrefix || ''}/_next/`, path: isServer && isWebpack5 && !dev ? path.join(outputPath, 'chunks') From 94339c3896a572816cf539302d07ec1668f9a9cf Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 17 Jun 2021 11:13:01 -0500 Subject: [PATCH 06/11] update build-output --- test/integration/build-output/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/build-output/test/index.test.js b/test/integration/build-output/test/index.test.js index 5893d7aa14569..233a760a02387 100644 --- a/test/integration/build-output/test/index.test.js +++ b/test/integration/build-output/test/index.test.js @@ -144,7 +144,7 @@ describe('Build Output', () => { const webpackSizeValue = webpackSize.endsWith('kB') ? parseFloat(webpackSize) : parseFloat(webpackSize) / 1000 - expect(webpackSizeValue).toBeCloseTo(gz ? 0.76 : 1.45, 2) + expect(webpackSizeValue).toBeCloseTo(gz ? 0.766 : 1.46, 2) expect(webpackSize.endsWith('kB') || webpackSize.endsWith(' B')).toBe( true ) From 21a785aa451c0932ac47b2153cc5d2f2bc4e0998 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 18 Jun 2021 12:56:33 +0200 Subject: [PATCH 07/11] Fix flakeyness between amphtml tests --- test/integration/amphtml/test/index.test.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/test/integration/amphtml/test/index.test.js b/test/integration/amphtml/test/index.test.js index 02a8f3cafdd40..85d8d4385f0b0 100644 --- a/test/integration/amphtml/test/index.test.js +++ b/test/integration/amphtml/test/index.test.js @@ -402,6 +402,8 @@ describe('AMP Usage', () => { it('should not reload unless the page is edited for an AMP page', async () => { let browser + const hmrTestPagePath = join(__dirname, '../', 'pages', 'hmr', 'test.js') + const originalContent = readFileSync(hmrTestPagePath, 'utf8') try { await renderViaHTTP(dynamicAppPort, '/hmr/test') @@ -409,15 +411,7 @@ describe('AMP Usage', () => { await check(() => browser.elementByCss('p').text(), /I'm an AMP page!/) const origDate = await browser.elementByCss('span').text() - const hmrTestPagePath = join( - __dirname, - '../', - 'pages', - 'hmr', - 'test.js' - ) - const originalContent = readFileSync(hmrTestPagePath, 'utf8') const editedContent = originalContent.replace( `This is the hot AMP page.`, 'replaced it!' @@ -456,6 +450,7 @@ describe('AMP Usage', () => { await check(() => getBrowserBodyText(browser), /I'm an AMP page!/) } finally { + writeFileSync(hmrTestPagePath, originalContent, 'utf8') await browser.close() } }) From 577dcc6dc55ba8a6ac76b13c48200cc62f3b6e00 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 18 Jun 2021 16:09:25 +0200 Subject: [PATCH 08/11] fix hot update path in amp-dev --- packages/next/client/dev/amp-dev.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/next/client/dev/amp-dev.js b/packages/next/client/dev/amp-dev.js index c4c829a680f53..f069e30f3ac4b 100644 --- a/packages/next/client/dev/amp-dev.js +++ b/packages/next/client/dev/amp-dev.js @@ -37,7 +37,12 @@ async function tryApplyUpdates() { return } try { - const res = await fetch(`${hotUpdatePath}${curHash}.hot-update.json`) + const res = await fetch( + typeof __webpack_runtime__ !== 'undefined' + ? // eslint-disable-next-line no-undef + `${hotUpdatePath}${curHash}.${__webpack_runtime__}.hot-update.json` + : `${hotUpdatePath}${curHash}..hot-update.json` + ) const jsonData = await res.json() const curPage = page === '/' ? 'index' : page // webpack 5 uses an array instead From 8d0b5ec28a7c76d324ed8cfcdf120d17b386e98a Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 18 Jun 2021 16:26:09 +0200 Subject: [PATCH 09/11] Update packages/next/client/dev/amp-dev.js --- packages/next/client/dev/amp-dev.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/dev/amp-dev.js b/packages/next/client/dev/amp-dev.js index f069e30f3ac4b..95735202a0fe6 100644 --- a/packages/next/client/dev/amp-dev.js +++ b/packages/next/client/dev/amp-dev.js @@ -41,7 +41,7 @@ async function tryApplyUpdates() { typeof __webpack_runtime__ !== 'undefined' ? // eslint-disable-next-line no-undef `${hotUpdatePath}${curHash}.${__webpack_runtime__}.hot-update.json` - : `${hotUpdatePath}${curHash}..hot-update.json` + : `${hotUpdatePath}${curHash}.hot-update.json` ) const jsonData = await res.json() const curPage = page === '/' ? 'index' : page From 41793fd7278b5e77e2960215e749487004de1fef Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 18 Jun 2021 18:08:52 +0200 Subject: [PATCH 10/11] use current webpack variable name --- packages/next/client/dev/amp-dev.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/client/dev/amp-dev.js b/packages/next/client/dev/amp-dev.js index 95735202a0fe6..c10a5ac1736f2 100644 --- a/packages/next/client/dev/amp-dev.js +++ b/packages/next/client/dev/amp-dev.js @@ -38,9 +38,9 @@ async function tryApplyUpdates() { } try { const res = await fetch( - typeof __webpack_runtime__ !== 'undefined' + typeof __webpack_runtime_id__ !== 'undefined' ? // eslint-disable-next-line no-undef - `${hotUpdatePath}${curHash}.${__webpack_runtime__}.hot-update.json` + `${hotUpdatePath}${curHash}.${__webpack_runtime_id__}.hot-update.json` : `${hotUpdatePath}${curHash}.hot-update.json` ) const jsonData = await res.json() From 2dd3e704d2547a86e7352ce929b50873e2dc5189 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 18 Jun 2021 18:30:26 +0200 Subject: [PATCH 11/11] Use correct variable --- packages/next/client/dev/amp-dev.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/client/dev/amp-dev.js b/packages/next/client/dev/amp-dev.js index 95735202a0fe6..c10a5ac1736f2 100644 --- a/packages/next/client/dev/amp-dev.js +++ b/packages/next/client/dev/amp-dev.js @@ -38,9 +38,9 @@ async function tryApplyUpdates() { } try { const res = await fetch( - typeof __webpack_runtime__ !== 'undefined' + typeof __webpack_runtime_id__ !== 'undefined' ? // eslint-disable-next-line no-undef - `${hotUpdatePath}${curHash}.${__webpack_runtime__}.hot-update.json` + `${hotUpdatePath}${curHash}.${__webpack_runtime_id__}.hot-update.json` : `${hotUpdatePath}${curHash}.hot-update.json` ) const jsonData = await res.json()