nextjs-require-cache-hot-reloader.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _sandbox = require("../../../server/web/sandbox");
  6. var _fs = require("fs");
  7. var _path = _interopRequireDefault(require("path"));
  8. var _isError = _interopRequireDefault(require("../../../lib/is-error"));
  9. function _interopRequireDefault(obj) {
  10. return obj && obj.__esModule ? obj : {
  11. default: obj
  12. };
  13. }
  14. const originModules = [
  15. require.resolve("../../../server/require"),
  16. require.resolve("../../../server/load-components"),
  17. ];
  18. const RUNTIME_NAMES = [
  19. "webpack-runtime",
  20. "webpack-api-runtime"
  21. ];
  22. function deleteCache(filePath) {
  23. try {
  24. filePath = (0, _fs).realpathSync(filePath);
  25. } catch (e) {
  26. if ((0, _isError).default(e) && e.code !== "ENOENT") throw e;
  27. }
  28. const mod = require.cache[filePath];
  29. if (mod) {
  30. // remove the child reference from the originModules
  31. for (const originModule of originModules){
  32. const parent = require.cache[originModule];
  33. if (parent) {
  34. const idx = parent.children.indexOf(mod);
  35. if (idx >= 0) parent.children.splice(idx, 1);
  36. }
  37. }
  38. // remove parent references from external modules
  39. for (const child of mod.children){
  40. child.parent = null;
  41. }
  42. delete require.cache[filePath];
  43. return true;
  44. }
  45. return false;
  46. }
  47. const PLUGIN_NAME = "NextJsRequireCacheHotReloader";
  48. class NextJsRequireCacheHotReloader {
  49. prevAssets = null;
  50. constructor(opts){
  51. this.hasServerComponents = opts.hasServerComponents;
  52. }
  53. apply(compiler) {
  54. compiler.hooks.assetEmitted.tap(PLUGIN_NAME, (_file, { targetPath , content })=>{
  55. deleteCache(targetPath);
  56. (0, _sandbox).clearModuleContext(targetPath, content.toString("utf-8"));
  57. });
  58. compiler.hooks.afterEmit.tap(PLUGIN_NAME, (compilation)=>{
  59. RUNTIME_NAMES.forEach((name)=>{
  60. const runtimeChunkPath = _path.default.join(compilation.outputOptions.path, `${name}.js`);
  61. deleteCache(runtimeChunkPath);
  62. });
  63. // we need to make sure to clear all server entries from cache
  64. // since they can have a stale webpack-runtime cache
  65. // which needs to always be in-sync
  66. const entries = [
  67. ...compilation.entries.keys()
  68. ].filter((entry)=>entry.toString().startsWith("pages/") || entry.toString().startsWith("app/"));
  69. entries.forEach((page)=>{
  70. const outputPath = _path.default.join(compilation.outputOptions.path, page + ".js");
  71. deleteCache(outputPath);
  72. });
  73. });
  74. }
  75. }
  76. exports.NextJsRequireCacheHotReloader = NextJsRequireCacheHotReloader;
  77. //# sourceMappingURL=nextjs-require-cache-hot-reloader.js.map