Skip to content

Commit c5e1e48

Browse files
timneutkensTimer
andauthored
Replace extra source line in webpack 5 (#14793)
Co-authored-by: Joe Haddad <[email protected]> Co-authored-by: Joe Haddad <[email protected]>
1 parent e84537f commit c5e1e48

File tree

9 files changed

+110
-29
lines changed

9 files changed

+110
-29
lines changed

packages/react-dev-overlay/src/middleware.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ function getSourcePath(source: string) {
5959
return source.substring(15)
6060
}
6161

62+
if (source.startsWith('webpack://')) {
63+
return source.substring(10)
64+
}
65+
6266
return source
6367
}
6468

packages/react-dev-overlay/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"sourceMap": true,
34
"esModuleInterop": true,
45
"target": "es3",
56
"lib": ["dom"],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*.d.ts
22
*.js
3+
*.js.map

packages/react-refresh-utils/ReactRefreshWebpackPlugin.ts

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { Compiler, Template, version } from 'webpack'
1+
import {
2+
Compiler,
3+
Template,
4+
// @ts-ignore exists in webpack 5
5+
RuntimeModule,
6+
// @ts-ignore exists in webpack 5
7+
RuntimeGlobals,
8+
version,
9+
} from 'webpack'
210

311
function webpack4(compiler: Compiler) {
412
// Webpack 4 does not have a method to handle interception of module
@@ -51,6 +59,64 @@ function webpack4(compiler: Compiler) {
5159
})
5260
}
5361

62+
function webpack5(compiler: Compiler) {
63+
class ReactRefreshRuntimeModule extends RuntimeModule {
64+
constructor() {
65+
super('react refresh', 5)
66+
}
67+
68+
generate() {
69+
// @ts-ignore This exists in webpack 5
70+
const { runtimeTemplate } = this.compilation
71+
return Template.asString([
72+
`${
73+
RuntimeGlobals.interceptModuleExecution
74+
}.push(${runtimeTemplate.basicFunction('options', [
75+
`${
76+
runtimeTemplate.supportsConst() ? 'const' : 'var'
77+
} originalFactory = options.factory;`,
78+
`options.factory = ${runtimeTemplate.basicFunction(
79+
'moduleObject, moduleExports, webpackRequire',
80+
[
81+
// Legacy CSS implementations will `eval` browser code in a Node.js
82+
// context to extract CSS. For backwards compatibility, we need to check
83+
// we're in a browser context before continuing.
84+
`${
85+
runtimeTemplate.supportsConst() ? 'const' : 'var'
86+
} hasRefresh = typeof self !== "undefined" && !!self.$RefreshInterceptModuleExecution$;`,
87+
`${
88+
runtimeTemplate.supportsConst() ? 'const' : 'var'
89+
} cleanup = hasRefresh ? self.$RefreshInterceptModuleExecution$(moduleObject.id) : ${
90+
runtimeTemplate.supportsArrowFunction()
91+
? '() => {}'
92+
: 'function() {}'
93+
};`,
94+
'try {',
95+
Template.indent(
96+
'originalFactory.call(this, moduleObject, moduleExports, webpackRequire);'
97+
),
98+
'} finally {',
99+
Template.indent(`cleanup();`),
100+
'}',
101+
]
102+
)}`,
103+
])})`,
104+
])
105+
}
106+
}
107+
108+
compiler.hooks.compilation.tap('ReactFreshWebpackPlugin', (compilation) => {
109+
// @ts-ignore Exists in webpack 5
110+
compilation.hooks.additionalTreeRuntimeRequirements.tap(
111+
'ReactFreshWebpackPlugin',
112+
(chunk: any) => {
113+
// @ts-ignore Exists in webpack 5
114+
compilation.addRuntimeModule(chunk, new ReactRefreshRuntimeModule())
115+
}
116+
)
117+
})
118+
}
119+
54120
class ReactFreshWebpackPlugin {
55121
apply(compiler: Compiler) {
56122
const webpackMajorVersion = parseInt(version ?? '', 10)
@@ -60,6 +126,10 @@ class ReactFreshWebpackPlugin {
60126
webpack4(compiler)
61127
break
62128
}
129+
case 5: {
130+
webpack5(compiler)
131+
break
132+
}
63133
default: {
64134
throw new Error(
65135
`ReactFreshWebpackPlugin does not support webpack v${webpackMajorVersion}.`

packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export default function () {
2525
// AMP / No-JS mode does not inject these helpers:
2626
'$RefreshHelpers$' in self
2727
) {
28-
const currentExports = module.__proto__.exports
29-
const prevExports = module.hot.data?.prevExports ?? null
28+
var currentExports = module.__proto__.exports
29+
var prevExports = module.hot.data?.prevExports ?? null
3030

3131
// This cannot happen in MainTemplate because the exports mismatch between
3232
// templating and execution.
@@ -40,7 +40,7 @@ export default function () {
4040
if (self.$RefreshHelpers$.isReactRefreshBoundary(currentExports)) {
4141
// Save the previous exports on update so we can compare the boundary
4242
// signatures.
43-
module.hot.dispose((data) => {
43+
module.hot.dispose(function (data) {
4444
data.prevExports = currentExports
4545
})
4646
// Unconditionally accept an update to this module, we'll check if it's
@@ -74,7 +74,7 @@ export default function () {
7474
// new exports made it ineligible for being a boundary.
7575
// We only care about the case when we were _previously_ a boundary,
7676
// because we already accepted this update (accidental side effect).
77-
const isNoLongerABoundary = prevExports !== null
77+
var isNoLongerABoundary = prevExports !== null
7878
if (isNoLongerABoundary) {
7979
module.hot.invalidate()
8080
}

packages/react-refresh-utils/internal/helpers.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ function registerExportsForReactRefresh(
6363
// (This is important for legacy environments.)
6464
return
6565
}
66-
for (const key in moduleExports) {
66+
for (var key in moduleExports) {
6767
if (isSafeExport(key)) {
6868
continue
6969
}
70-
const exportValue = moduleExports[key]
71-
const typeID = moduleID + ' %exports% ' + key
70+
var exportValue = moduleExports[key]
71+
var typeID = moduleID + ' %exports% ' + key
7272
RefreshRuntime.register(exportValue, typeID)
7373
}
7474
}
@@ -81,14 +81,14 @@ function isReactRefreshBoundary(moduleExports: unknown): boolean {
8181
// Exit if we can't iterate over exports.
8282
return false
8383
}
84-
let hasExports = false
85-
let areAllExportsComponents = true
86-
for (const key in moduleExports) {
84+
var hasExports = false
85+
var areAllExportsComponents = true
86+
for (var key in moduleExports) {
8787
hasExports = true
8888
if (isSafeExport(key)) {
8989
continue
9090
}
91-
const exportValue = moduleExports[key]
91+
var exportValue = moduleExports[key]
9292
if (!RefreshRuntime.isLikelyComponentType(exportValue)) {
9393
areAllExportsComponents = false
9494
}
@@ -100,12 +100,12 @@ function shouldInvalidateReactRefreshBoundary(
100100
prevExports: unknown,
101101
nextExports: unknown
102102
): boolean {
103-
const prevSignature = getRefreshBoundarySignature(prevExports)
104-
const nextSignature = getRefreshBoundarySignature(nextExports)
103+
var prevSignature = getRefreshBoundarySignature(prevExports)
104+
var nextSignature = getRefreshBoundarySignature(nextExports)
105105
if (prevSignature.length !== nextSignature.length) {
106106
return true
107107
}
108-
for (let i = 0; i < nextSignature.length; i++) {
108+
for (var i = 0; i < nextSignature.length; i++) {
109109
if (prevSignature[i] !== nextSignature[i]) {
110110
return true
111111
}
@@ -114,25 +114,25 @@ function shouldInvalidateReactRefreshBoundary(
114114
}
115115

116116
function getRefreshBoundarySignature(moduleExports: unknown): Array<unknown> {
117-
const signature = []
117+
var signature = []
118118
signature.push(RefreshRuntime.getFamilyByType(moduleExports))
119119
if (moduleExports == null || typeof moduleExports !== 'object') {
120120
// Exit if we can't iterate over exports.
121121
// (This is important for legacy environments.)
122122
return signature
123123
}
124-
for (const key in moduleExports) {
124+
for (var key in moduleExports) {
125125
if (isSafeExport(key)) {
126126
continue
127127
}
128-
const exportValue = moduleExports[key]
128+
var exportValue = moduleExports[key]
129129
signature.push(key)
130130
signature.push(RefreshRuntime.getFamilyByType(exportValue))
131131
}
132132
return signature
133133
}
134134

135-
let isUpdateScheduled: boolean = false
135+
var isUpdateScheduled: boolean = false
136136
function scheduleUpdate() {
137137
if (isUpdateScheduled) {
138138
return
@@ -143,7 +143,7 @@ function scheduleUpdate() {
143143
}
144144

145145
isUpdateScheduled = true
146-
setTimeout(() => {
146+
setTimeout(function () {
147147
isUpdateScheduled = false
148148

149149
// Only trigger refresh if the webpack HMR state is idle

packages/react-refresh-utils/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"webpack": "^4"
2424
},
2525
"devDependencies": {
26-
"react-refresh": "0.8.3",
27-
"webpack": "^4.42.1"
26+
"react-refresh": "0.8.3"
2827
}
2928
}

packages/react-refresh-utils/runtime.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,29 @@ declare const self: Window & RefreshRuntimeGlobals
1414
RefreshRuntime.injectIntoGlobalHook(self)
1515

1616
// noop fns to prevent runtime errors during initialization
17-
self.$RefreshReg$ = () => {}
18-
self.$RefreshSig$ = () => (type) => type
17+
self.$RefreshReg$ = function () {}
18+
self.$RefreshSig$ = function () {
19+
return function (type) {
20+
return type
21+
}
22+
}
1923

2024
// Register global helpers
2125
self.$RefreshHelpers$ = RefreshHelpers
2226

2327
// Register a helper for module execution interception
2428
self.$RefreshInterceptModuleExecution$ = function (webpackModuleId) {
25-
const prevRefreshReg = self.$RefreshReg$
26-
const prevRefreshSig = self.$RefreshSig$
29+
var prevRefreshReg = self.$RefreshReg$
30+
var prevRefreshSig = self.$RefreshSig$
2731

28-
self.$RefreshReg$ = (type, id) => {
32+
self.$RefreshReg$ = function (type, id) {
2933
RefreshRuntime.register(type, webpackModuleId + ' ' + id)
3034
}
3135
self.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform
3236

3337
// Modeled after `useEffect` cleanup pattern:
3438
// https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup
35-
return () => {
39+
return function () {
3640
self.$RefreshReg$ = prevRefreshReg
3741
self.$RefreshSig$ = prevRefreshSig
3842
}

packages/react-refresh-utils/tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
22
"compilerOptions": {
3+
"module": "commonjs",
4+
"sourceMap": true,
35
"esModuleInterop": true,
4-
"target": "es3",
6+
"target": "es2015",
57
"lib": ["dom"],
68
"downlevelIteration": true,
79
"preserveWatchOutput": true

0 commit comments

Comments
 (0)