-
Notifications
You must be signed in to change notification settings - Fork 27.2k
/
amp-dev.ts
119 lines (108 loc) · 3.38 KB
/
amp-dev.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* globals __webpack_hash__ */
import { displayContent } from './fouc'
import initOnDemandEntries from './on-demand-entries-client'
import { addMessageListener, connectHMR } from './error-overlay/websocket'
import { HMR_ACTIONS_SENT_TO_BROWSER } from '../../server/dev/hot-reloader-types'
declare global {
const __webpack_runtime_id__: string
}
const data = JSON.parse(
(document.getElementById('__NEXT_DATA__') as any).textContent
)
window.__NEXT_DATA__ = data
let { assetPrefix, page } = data
assetPrefix = assetPrefix || ''
let mostRecentHash: null | string = null
/* eslint-disable-next-line */
let curHash = __webpack_hash__
const hotUpdatePath =
assetPrefix + (assetPrefix.endsWith('/') ? '' : '/') + '_next/static/webpack/'
// Is there a newer version of this code available?
function isUpdateAvailable() {
// __webpack_hash__ is the hash of the current compilation.
// It's a global variable injected by Webpack.
/* eslint-disable-next-line */
return mostRecentHash !== __webpack_hash__
}
// Webpack disallows updates in other states.
function canApplyUpdates() {
// @ts-expect-error TODO: module.hot exists but type needs to be added. Can't use `as any` here as webpack parses for `module.hot` calls.
return module.hot.status() === 'idle'
}
// This function reads code updates on the fly and hard
// reloads the page when it has changed.
async function tryApplyUpdates() {
if (!isUpdateAvailable() || !canApplyUpdates()) {
return
}
try {
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
const pageUpdated = (
Array.isArray(jsonData.c) ? jsonData.c : Object.keys(jsonData.c)
).some((mod: string) => {
return (
mod.indexOf(
`pages${curPage.startsWith('/') ? curPage : `/${curPage}`}`
) !== -1 ||
mod.indexOf(
`pages${curPage.startsWith('/') ? curPage : `/${curPage}`}`.replace(
/\//g,
'\\'
)
) !== -1
)
})
if (pageUpdated) {
window.location.reload()
} else {
curHash = mostRecentHash as string
}
} catch (err) {
console.error('Error occurred checking for update', err)
window.location.reload()
}
}
addMessageListener((message) => {
if (!('action' in message)) {
return
}
try {
// actions which are not related to amp-dev
if (
message.action === HMR_ACTIONS_SENT_TO_BROWSER.SERVER_ERROR ||
message.action === HMR_ACTIONS_SENT_TO_BROWSER.DEV_PAGES_MANIFEST_UPDATE
) {
return
}
if (
message.action === HMR_ACTIONS_SENT_TO_BROWSER.SYNC ||
message.action === HMR_ACTIONS_SENT_TO_BROWSER.BUILT
) {
if (!message.hash) {
return
}
mostRecentHash = message.hash
tryApplyUpdates()
} else if (message.action === HMR_ACTIONS_SENT_TO_BROWSER.RELOAD_PAGE) {
window.location.reload()
}
} catch (err: any) {
console.warn(
'[HMR] Invalid message: ' + message + '\n' + (err?.stack ?? '')
)
}
})
connectHMR({
assetPrefix,
path: '/_next/webpack-hmr',
})
displayContent()
initOnDemandEntries(data.page)