You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.3 KiB

  1. 'use strict';
  2. var isNative = /\.node$/;
  3. function forEach(obj, callback) {
  4. for ( var key in obj ) {
  5. if (!Object.prototype.hasOwnProperty.call(obj, key)) {
  6. continue;
  7. }
  8. callback(key);
  9. }
  10. }
  11. function assign(target, source) {
  12. forEach(source, function (key) {
  13. target[key] = source[key];
  14. });
  15. return target;
  16. }
  17. function clearCache(requireCache) {
  18. forEach(requireCache, function (resolvedPath) {
  19. if (!isNative.test(resolvedPath)) {
  20. delete requireCache[resolvedPath];
  21. }
  22. });
  23. }
  24. module.exports = function (requireCache, callback, callbackForModulesToKeep, module) {
  25. var originalCache = assign({}, requireCache);
  26. clearCache(requireCache);
  27. if (callbackForModulesToKeep) {
  28. var originalModuleChildren = module.children ? module.children.slice() : false; // Creates a shallow copy of module.children
  29. callbackForModulesToKeep();
  30. // Lists the cache entries made by callbackForModulesToKeep()
  31. var modulesToKeep = [];
  32. forEach(requireCache, function (key) {
  33. modulesToKeep.push(key);
  34. });
  35. // Discards the modules required in callbackForModulesToKeep()
  36. clearCache(requireCache);
  37. if (module.children) { // Only true for node.js
  38. module.children = originalModuleChildren; // Removes last references to modules required in callbackForModulesToKeep() -> No memory leak
  39. }
  40. // Takes the cache entries of the original cache in case the modules where required before
  41. for ( var i = 0; i < modulesToKeep.length; i+=1 ) {
  42. if (originalCache[modulesToKeep[i]]) {
  43. requireCache[modulesToKeep[i]] = originalCache[modulesToKeep[i]];
  44. }
  45. }
  46. }
  47. var freshModule = callback();
  48. var stealthCache = callbackForModulesToKeep ? assign({}, requireCache) : false;
  49. clearCache(requireCache);
  50. if (callbackForModulesToKeep) {
  51. // In case modules to keep were required inside the stealthy require for the first time, copy them to the restored cache
  52. for ( var k = 0; k < modulesToKeep.length; k+=1 ) {
  53. if (stealthCache[modulesToKeep[k]]) {
  54. requireCache[modulesToKeep[k]] = stealthCache[modulesToKeep[k]];
  55. }
  56. }
  57. }
  58. assign(requireCache, originalCache);
  59. return freshModule;
  60. };