Function to reset module script require cache in plugins

Plugins want to flush the require cache so that they can run code that you’re actively working on.

Right now you have to clone the script before you do this, which gives you a fresh instance with no require cache.

This is a problem because lua loses hierarchical context when this happens. The game doesn’t know where this cloned module is supposed to exist. Debugging tools can’t associate the clone script with the original.

It becomes impossible to debug scripts being run by a plugin.

So I want a function that would let me wipe the cache of a module so that it can be required again.

10 Likes

It’s messy and will probably deoptimize luau, but there is one way you can do this.

local cache = {}
local requiring = {}
local function nocache_require( moduleScript: ModuleScript )
	local hasCache = cache[ moduleScript ]
	if ( hasCache ) then return hasCache end
	if ( requiring[ moduleScript ] ) then
		table.insert( requiring[ moduleScript ], coroutine.running() )
		return coroutine.yield()
	end
	requiring[ moduleScript ] = {}

	local module, parseError = loadstring( moduleScript.Source )
	if ( parseError ) then error( parseError, 2 ) end

	local moduleEnvironment = setmetatable( {
		script = moduleScript,
		require = nocache_require, -- this cache system is required for this to work properly, just use resetCache when necessary
	}, {
		__index = getfenv( module )
	} )

	setfenv( module, moduleEnvironment )

	local output = module() -- let's assume that you are following the rules of module scripts
	
	for index, thread in requiring[ moduleScript ] do
		task.spawn( thread, output )
		requiring[ moduleScript ][ index ] = nil
	end
	requiring[ moduleScript ] = nil
	
	return output
end

local function resetCache()
	table.clear( cache )
end

But yeah, it really sucks that we need a workaround for this to work. I vouch that we need a way to clear the module script cache-- even if only usable with plugins.

Edit: I just realized this is a year old. I thought it meant January 22nd instead of 2022. Oops.

1 Like

This should really be an engine feature, and work across all of Roblox.

2 Likes