This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ReactRefreshHotModule = require.resolve('./ReactRefreshHotModule'); | |
const ReactRefreshHotModuleInjection = ` | |
const ReactRefreshHotModule = require('${ReactRefreshHotModule}'); | |
if (ReactRefreshHotModule.isReactRefreshBoundary(module.exports || module.__proto__exports)) { | |
module.hot.accept(module.id, () => { | |
ReactRefreshHotModule.enqueueUpdate(); | |
}); | |
} | |
`; | |
function HotModuleLoader(source) { | |
return source + ReactRefreshHotModuleInjection; | |
} | |
module.exports = HotModuleLoader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ReactRefreshRuntimeInjection = ` | |
if (process.env.NODE_ENV !== 'production' && typeof window !== 'undefined') { | |
const ReactRefreshRuntime = require('react-refresh/runtime'); | |
ReactRefreshRuntime.injectIntoGlobalHook(window); | |
window.$RefreshReg$ = () => {}; | |
window.$RefreshSig$ = () => type => type; | |
window.__setupReactRefreshForModule = (moduleId) => { | |
const prevRefreshReg = window.$RefreshReg$; | |
const prevRefreshSig = window.$RefreshSig$; | |
window.$RefreshReg$ = (type, id) => { | |
const fullId = moduleId + ' ' + id; | |
ReactRefreshRuntime.register(type, fullId); | |
}; | |
window.$RefreshSig$ = ReactRefreshRuntime.createSignatureFunctionForTransform; | |
return () => { | |
window.$RefreshReg$ = prevRefreshReg; | |
window.$RefreshSig$ = prevRefreshSig; | |
}; | |
}; | |
} | |
`; | |
function ReactDOMLoader(source) { | |
return ReactRefreshRuntimeInjection + source; | |
} | |
module.exports = ReactDOMLoader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ReactRefreshRuntime = require('react-refresh/runtime'); | |
let timerId; | |
function enqueueUpdate() { | |
clearTimeout(timerId); | |
timerId = setTimeout(() => { | |
ReactRefreshRuntime.performReactRefresh(); | |
}, 30); | |
} | |
function isReactRefreshBoundary(moduleExports) { | |
if (ReactRefreshRuntime.isLikelyComponentType(moduleExports)) { | |
return true; | |
} | |
if (moduleExports == null || typeof moduleExports !== 'object') { | |
// Exit if we can't iterate over exports. | |
return false; | |
} | |
let hasExports = false; | |
let areAllExportsComponents = true; | |
for (const key in moduleExports) { | |
hasExports = true; | |
if (key === '__esModule') { | |
continue; | |
} | |
const desc = Object.getOwnPropertyDescriptor(moduleExports, key); | |
if (desc && desc.get) { | |
// Don't invoke getters as they may have side effects. | |
return false; | |
} | |
const exportValue = moduleExports[key]; | |
if (!ReactRefreshRuntime.isLikelyComponentType(exportValue)) { | |
areAllExportsComponents = false; | |
} | |
} | |
return hasExports && areAllExportsComponents; | |
} | |
module.exports = { | |
isReactRefreshBoundary, | |
enqueueUpdate, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ReactRefreshPlugin { | |
apply(compiler) { | |
if (process.env.NODE_ENV !== 'development') { | |
return; | |
} | |
compiler.hooks.normalModuleFactory.tap('ReactRefreshPlugin', (nmf) => { | |
nmf.hooks.afterResolve.tap('ReactRefreshPlugin', (data) => { | |
if (data.rawRequest === 'react-dom') { | |
data.loaders.unshift({ | |
loader: require.resolve('./ReactDOMLoader'), | |
}); | |
} else if (/\.jsx?$/.test(data.resource) && !/node_modules/.test(data.resource)) { | |
data.loaders.unshift({ | |
loader: require.resolve('./HotModuleLoader'), | |
}); | |
} | |
return data; | |
}); | |
}); | |
compiler.hooks.compilation.tap('ReactRefreshPlugin', (compilation) => { | |
compilation.mainTemplate.hooks.require.tap('ReactRefreshPlugin', (source) => { | |
const lines = source.split('\n'); | |
const moduleInitializationLineNumber = lines.findIndex((line) => { | |
return line.startsWith('modules[moduleId].call'); | |
}); | |
if (moduleInitializationLineNumber === -1) { | |
return source; | |
} | |
lines.splice( | |
moduleInitializationLineNumber, | |
1, | |
'var cleanup = window.__setupReactRefreshForModule', | |
' ? window.__setupReactRefreshForModule(module.i)', | |
' : function() {};', | |
'try {', | |
' ' + lines[moduleInitializationLineNumber], | |
'} finally {', | |
' cleanup();', | |
'}', | |
); | |
return lines.join('\n'); | |
}); | |
}); | |
} | |
} | |
module.exports = ReactRefreshPlugin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment