Lune does not cache require results across files
Closed this issue · 4 comments
The results of requiring a file is only cached in that specific file. This means that if two different scripts both require a script, it will run twice, which can be very problematic for modules that are supposed to contain a global state.
Simple reproduction:
test1.luau (file to run):
local result1 = require("./test3")
local result2 = require("./test3")
local result3 = require("./test2")
print(result1 == result2, result1 == result3) --> true, false
test2.luau:
return require("./test3")
test3.luau:
print("test3 ran") --> test3 ran (x2)
return {}
This bit me pretty hard recently. I was trying to create a Logging class which would be instantiated and returned in a logging.luau
file to keep around a singleton. It took me a while to figure out that every time I required that file I was getting back a brand new Logging instance. I would really like to see support for module caching by default, with a way to bypass the cache in special situations (I think Jest would benefit from this in particular for its module mocking)
Just ran into this trying to write a basic testing framework, is the only workaround to use true globals instead?
I added a test that demonstrates the issue and does indeed fail, opened a draft PR with the test here: #170
I would not know how to even begin solving the issue, but hopefully the test is useful
Oh nice, looks like @kennethloeffler has a PR fixing this already, so speedy!
If for any reason someone is unable to use a lune version that has the fix in the future, I made a little workaround that is quite un-intrusive and still works with lsp (luau-lsp at least).
Gist for the workaround module here: https://gist.github.com/itsfrank/c3e193338612eb00324dc2340aaffa79
You can use it like so:
local some_module_state = {}
some_module_state.foo = "bar"
some_module_state = require("modulestate.luau").get_state("<unique name>", some_module_state)
-- from here on out, `some_module_state` will have the values from the global state
-- but luau-lsp still treats it like a local table, so typing `some_module_state.` will suggest `foo` with type string
When the fix is merged you should be able to just delete the require("modulestate.luau").get_state
line and everything should work as intended