Skip to content

Commit

Permalink
Add runtime to hotUpdateMainFilename (#26256)
Browse files Browse the repository at this point in the history
Updates the hotUpdateChunk to include `[runtime]` for web workers support.

Fixes #26152
Fixes #19865
Fixes #26144

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.

## Documentation / Examples

- [ ] Make sure the linting passes
  • Loading branch information
timneutkens committed Jun 18, 2021
1 parent 98acfaf commit 88ed526
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 15 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,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",
Expand Down
10 changes: 5 additions & 5 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ 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: {
Expand Down Expand Up @@ -611,9 +611,9 @@ 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
splitChunksConfig = isWebpack5 ? false : splitChunksConfigs.dev
} else {
splitChunksConfig = splitChunksConfigs.prodGranular
}
Expand Down Expand Up @@ -940,7 +940,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')
Expand All @@ -959,7 +959,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
Expand Down
7 changes: 6 additions & 1 deletion packages/next/client/dev/amp-dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -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_id__ !== 'undefined'
? // eslint-disable-next-line no-undef
`${hotUpdatePath}${curHash}.${__webpack_runtime_id__}.hot-update.json`
: `${hotUpdatePath}${curHash}.hot-update.json`
)
const jsonData = await res.json()
const curPage = page === '/' ? 'index' : page
// webpack 5 uses an array instead
Expand Down
11 changes: 3 additions & 8 deletions test/integration/amphtml/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,22 +402,16 @@ 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')

browser = await webdriver(dynamicAppPort, '/hmr/amp')
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!'
Expand Down Expand Up @@ -456,6 +450,7 @@ describe('AMP Usage', () => {

await check(() => getBrowserBodyText(browser), /I'm an AMP page!/)
} finally {
writeFileSync(hmrTestPagePath, originalContent, 'utf8')
await browser.close()
}
})
Expand Down
2 changes: 1 addition & 1 deletion test/integration/build-output/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
17 changes: 17 additions & 0 deletions test/integration/worker-webpack5/lib/sharedCode.js
Original file line number Diff line number Diff line change
@@ -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)
}
}
8 changes: 8 additions & 0 deletions test/integration/worker-webpack5/lib/worker.js
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions test/integration/worker-webpack5/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {}
38 changes: 38 additions & 0 deletions test/integration/worker-webpack5/pages/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<main>
<h1>$RefreshRegistry repro</h1>
<div id="web-status">Web: {expensiveWebStatus}</div>
<div id="worker-status">Worker: {expensiveWorkerStatus}</div>
</main>
)
}
58 changes: 58 additions & 0 deletions test/integration/worker-webpack5/test/index.test.js
Original file line number Diff line number Diff line change
@@ -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()
})
})
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8488,6 +8488,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"
Expand Down

0 comments on commit 88ed526

Please sign in to comment.