There’s other engines that use this kind of thing, probably not the exact same thing though, but I’m pretty glad it’s made its way over to Roblox either way!! It’s about time.
Because requiring like that is not possible on vanilla Luau, this is only possible on Roblox, in filesystem projects, you can’t put files under files the way Roblox allows you to put instances inside instances
How could the new “require by string” feature be strategically utilized to streamline module management and improve code readability, especially in projects that rely on external tools like Rojo or involve cross-platform Luau development?
This has been answered somewhat by the Luau team on Discord, but for the sake of repeating it publicly (noting that I’m not a Roblox employee and thus my words mean nothing, and I am also paraphrasing):
The work required to get aliasing is roughly the same work needed to establish what a “library” is for Roblox (“project-relative requires” can be thought of as an equivalent to an aliases that points to the root of a library), and they felt it wasn’t worth blocking the release of require-by-string over.
This is one of their bigger priorities right now, so I’d expect at least an update on it soon™. This won’t be a Packages situation where the feature is half baked and sits for years.
Honestly this is a horrible reason to inconvenience literally everybody else that wants to use these features.
It’s more logical to take both approaches and make it even more convenient for people who are only working with Roblox, rather than inconveniencing everybody for cross-runtime compatibility’s sake. People who aren’t only working with Roblox can just code it in a way where it’s compatible for what they’re trying to achieve.
Ran into an issue when using require-by-string today, I believe it may be intended behavior but just want to confirm:
If I require my modules at the top of my script, these are equivalent, as stated in the announcement:
local Module = require(script.Parent.Parent.Folder.ModuleScript)
local SameModule = require("../Folder/ModuleScript")
However, if I am requiring the module inside of a function, they are not equivalent:
--No longer requiring the module out here.
local function DoSomethingWithModule()
local Module = require(script.Parent.Parent.Folder.ModuleScript) --Works
local SameModule = require("../Folder/ModuleScript") --Errors
end
return DoSomethingWithModule --will be called in a different script
I’m assuming the errors are happening because by the time the require-by-string line executes, it is technically running in another script that required the function above, so the Parent reference is not the same? So it may not be a bug? but was still a bit confusing to me because I thought the require-by-string statement was truly equivalent.
(I’m not using Rojo or anything, just vanilla Studio for this example)
Woah, a New Feature is going to be in the ModuleScript… This is such a Wild, Great News scenario! If the Require-By-String thing was in Studio, That ModuleScript should Work…
Don’t worry, you can still store Vector3’s and Color3’s, you’ll just have to convert each value (Red, Green Blue or X, Y, Z) into their own individual numbers and unpack them when you want to use it.
Currently really the only good way to do it is to store it as a buffer containing all the modifiable properties of the Instance, and then storing them similarly to how C stores structs (sequentially).
I honestly don’t know how a first-party implementation would be better than this considering it’s already pretty small (like less than 120 bytes to store all properties of a Part), and you can make it even smaller by making assumptions suiting your needs (for example if all your parts are red you don’t need to store color)
Honestly really surprised there’s no way to reference the current script in this without naming it.
I’m constantly adding other child scripts into one parent script that manages all of them and it really would be nice if there was some equivalent to require(script.Child) in this syntax instead of require(‘./modName/Child’)
E.g. some sort of require(‘script/Child’) or require(‘$child’) or require(‘/child’) or something
I know I could still just use script.Child, but it would be nice to stay consistent with my require format and this in general seems like it’s going to become a more powerful way once aliasing comes.
I came here just to suggest the same thing, yeah! “script/Child” would be an absolute path which they do not support yet, so I would rather prefer some other prefix like “$” or something else instead of “.” to access the current script level, agreed. I mean … of course normally you cannot put files inside of files in the File Explorer but Roblox supports that so it would be cool if we got this functionality in string requires, too.
This is not intended behavior, and a fix will be in shortly—thank you for flagging it! An exported function (a closure) is expected to capture its environment, including the context from which require-by-string is resolved.
In the meantime, I wouldn’t recommend relying on the current behavior. If you’d like the correct behavior right now, I’d recommend performing the actual require-by-string call outside of the closure, storing the result in a variable, and referring to it inside the closure using the variable:
-- For now, keep outside of closure
local result = require("../Folder/ModuleScript")
local function DoSomethingWithModule()
print(result)
end
return DoSomethingWithModule