getRefreshModuleRuntime.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /**
  2. * @typedef ModuleRuntimeOptions {Object}
  3. * @property {boolean} const Use ES6 `const` and `let` in generated runtime code.
  4. * @property {'cjs' | 'esm'} moduleSystem The module system to be used.
  5. */
  6. /**
  7. * Generates code appended to each JS-like module for react-refresh capabilities.
  8. *
  9. * `__react_refresh_utils__` will be replaced with actual utils during source parsing by `webpack.ProvidePlugin`.
  10. *
  11. * [Reference for Runtime Injection](https://github.com/webpack/webpack/blob/b07d3b67d2252f08e4bb65d354a11c9b69f8b434/lib/HotModuleReplacementPlugin.js#L419)
  12. * [Reference for HMR Error Recovery](https://github.com/webpack/webpack/issues/418#issuecomment-490296365)
  13. *
  14. * @param {import('webpack').Template} Webpack's templating helpers.
  15. * @param {ModuleRuntimeOptions} options The refresh module runtime options.
  16. * @returns {string} The refresh module runtime template.
  17. */
  18. function getRefreshModuleRuntime(Template, options) {
  19. const constDeclaration = options.const ? 'const' : 'var';
  20. const letDeclaration = options.const ? 'let' : 'var';
  21. const webpackHot = options.moduleSystem === 'esm' ? 'import.meta.webpackHot' : 'module.hot';
  22. return Template.asString([
  23. `${constDeclaration} $ReactRefreshModuleId$ = __webpack_require__.$Refresh$.moduleId;`,
  24. `${constDeclaration} $ReactRefreshCurrentExports$ = __react_refresh_utils__.getModuleExports(`,
  25. Template.indent('$ReactRefreshModuleId$'),
  26. ');',
  27. '',
  28. 'function $ReactRefreshModuleRuntime$(exports) {',
  29. Template.indent([
  30. `if (${webpackHot}) {`,
  31. Template.indent([
  32. `${letDeclaration} errorOverlay;`,
  33. "if (typeof __react_refresh_error_overlay__ !== 'undefined') {",
  34. Template.indent('errorOverlay = __react_refresh_error_overlay__;'),
  35. '}',
  36. `${letDeclaration} testMode;`,
  37. "if (typeof __react_refresh_test__ !== 'undefined') {",
  38. Template.indent('testMode = __react_refresh_test__;'),
  39. '}',
  40. 'return __react_refresh_utils__.executeRuntime(',
  41. Template.indent([
  42. 'exports,',
  43. '$ReactRefreshModuleId$,',
  44. `${webpackHot},`,
  45. 'errorOverlay,',
  46. 'testMode',
  47. ]),
  48. ');',
  49. ]),
  50. '}',
  51. ]),
  52. '}',
  53. '',
  54. "if (typeof Promise !== 'undefined' && $ReactRefreshCurrentExports$ instanceof Promise) {",
  55. Template.indent('$ReactRefreshCurrentExports$.then($ReactRefreshModuleRuntime$);'),
  56. '} else {',
  57. Template.indent('$ReactRefreshModuleRuntime$($ReactRefreshCurrentExports$);'),
  58. '}',
  59. ]);
  60. }
  61. module.exports = getRefreshModuleRuntime;