82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | var isNative = /\.node$/; | ||
|  | 
 | ||
|  | function forEach(obj, callback) { | ||
|  |     for ( var key in obj ) { | ||
|  |         if (!Object.prototype.hasOwnProperty.call(obj, key)) { | ||
|  |             continue; | ||
|  |         } | ||
|  |         callback(key); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | function assign(target, source) { | ||
|  |     forEach(source, function (key) { | ||
|  |         target[key] = source[key]; | ||
|  |     }); | ||
|  |     return target; | ||
|  | } | ||
|  | 
 | ||
|  | function clearCache(requireCache) { | ||
|  |     forEach(requireCache, function (resolvedPath) { | ||
|  |         if (!isNative.test(resolvedPath)) { | ||
|  |             delete requireCache[resolvedPath]; | ||
|  |         } | ||
|  |     }); | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = function (requireCache, callback, callbackForModulesToKeep, module) { | ||
|  | 
 | ||
|  |     var originalCache = assign({}, requireCache); | ||
|  |     clearCache(requireCache); | ||
|  | 
 | ||
|  |     if (callbackForModulesToKeep) { | ||
|  | 
 | ||
|  |         var originalModuleChildren = module.children ? module.children.slice() : false; // Creates a shallow copy of module.children
 | ||
|  | 
 | ||
|  |         callbackForModulesToKeep(); | ||
|  | 
 | ||
|  |         // Lists the cache entries made by callbackForModulesToKeep()
 | ||
|  |         var modulesToKeep = []; | ||
|  |         forEach(requireCache, function (key) { | ||
|  |             modulesToKeep.push(key); | ||
|  |         }); | ||
|  | 
 | ||
|  |         // Discards the modules required in callbackForModulesToKeep()
 | ||
|  |         clearCache(requireCache); | ||
|  | 
 | ||
|  |         if (module.children) { // Only true for node.js
 | ||
|  |             module.children = originalModuleChildren; // Removes last references to modules required in callbackForModulesToKeep() -> No memory leak
 | ||
|  |         } | ||
|  | 
 | ||
|  |         // Takes the cache entries of the original cache in case the modules where required before
 | ||
|  |         for ( var i = 0; i < modulesToKeep.length; i+=1 ) { | ||
|  |             if (originalCache[modulesToKeep[i]]) { | ||
|  |                 requireCache[modulesToKeep[i]] = originalCache[modulesToKeep[i]]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |     } | ||
|  | 
 | ||
|  |     var freshModule = callback(); | ||
|  | 
 | ||
|  |     var stealthCache = callbackForModulesToKeep ? assign({}, requireCache) : false; | ||
|  | 
 | ||
|  |     clearCache(requireCache); | ||
|  | 
 | ||
|  |     if (callbackForModulesToKeep) { | ||
|  |         // In case modules to keep were required inside the stealthy require for the first time, copy them to the restored cache
 | ||
|  |         for ( var k = 0; k < modulesToKeep.length; k+=1 ) { | ||
|  |             if (stealthCache[modulesToKeep[k]]) { | ||
|  |                 requireCache[modulesToKeep[k]] = stealthCache[modulesToKeep[k]]; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     assign(requireCache, originalCache); | ||
|  | 
 | ||
|  |     return freshModule; | ||
|  | 
 | ||
|  | }; |