Import - An easy way to require multiple modules at once

This module is a super simple one which allows you to require as many modules as you’d like at a single time.

Here’s an example of it’s usage:

local Import = require(path.to.module)
local Module1,Module2,Module3 = Import(path.to.one,path.to.two,path.to.three)

Source code if you want to use it:

function Import(...:ModuleScript)
	local ModulesToImport = table.pack(...)
	local ImportedModules = {}
	for _,module in ipairs(ModulesToImport) do
		if not typeof(module) == "Instance" or not module:IsA("ModuleScript") then warn("Failed to import",module,"(not a ModuleScript)") continue end
		local ImportedModule = require(module)
		if not ImportedModule then warn("Failed to import",module) continue end
		table.insert(ImportedModules,ImportedModule)
	end
	return table.unpack(ImportedModules)
end

return Import 
7 Likes

How about get modules from instance, as children.

I’m a bit confused by what you mean?

What exactly is the point here. Can’t we do something like

local Module1,Module2,Module3 = require(game.Workspace.sussy), require(game.Workspace.baka), require(game.Workspace.Amogus)
1 Like

Sure, you can. The point is mainly for syntax purposes/readability. Looks much nicer than repetitive require() calls

1 Like

The module makes it more readable and easier to do, saves you from having to type require() for each one, plus if you use variables for the module instances you can just do

local A,B,C = Import(One,Two,Three)

Honestly, I personally think that’s pointless to do that. In fact, it might affect the script looks more complex and hard to read. I can just give a quick example to explain all of it. Let’s say you have to require five different module scripts in the script. It might end up being like this:

local Import = require(path.to.module)
local Module1, Module2, Module3, Module4, Module5 = Import(path.to.one, path.to.two, script.to.one, script.Parent.Parent.to.one, script.to.then.five)

You can clearly see that it’s hard to read and edit due to the length of the code. Instead of using a module script that requires multiple modules scripts at once, I highly recommend handling your modules in a normal way.

Well, if you hate repetitive writing require(), you can just set a metastable with __index metamethod and doing it like this way:

local R = setmetatable({}, {
	__index = function(tab, Modules)
		return require(Modules) or nil
	end,
});

local A = R[script.ModuleScript]

At this point, it’s gonna be easier to read and you don’t need to type require() that much. Kill two birds with one stone.

Edited:
Other recommendation: You can also use the __call metamethod to archive it in the other way.

I know, I’ve done something similar. I was just explaining why someone would do this. Not everyone uses metatables or understands it enough for me to encourage so I just don’t bring them up.

I was just trying to show that you can also use this way to require the module scripts without repeatedly writing require() that much. Even you don’t understand the metastable, it’s not going to be a big deal, so dw.

1 Like

If you compare that example to this:

local Import = require(path.to.module)
local Module1, Module2, Module3, Module4, Module5 = require(path.to.one), require(path.to.two), require(script.to.one), require(script.Parent.Parent.to.one), require(script.to.then.five)

It’s much more readable & saves you from typing require() a bunch.

Honestly. you can just change the way you write this. Instead of writing all of them in one line, require them on multiple line would be easiler to read and edit:

local Module1 = require(path.to.one)
local Module2 = require(path.to.two)
local Module3 = require(path.to.three)
local Module4 = require(path.to.four)
local Module5 = require(path.to.five)

In addition, as I said if you actually hate repetitive writing require() , you can just set a metastable with __index metamethod and doing it like this way:

local R = setmetatable({}, {
	__index = function(tab, Modules)
		return require(Modules) or nil
	end,
});

local Module1 = R[path.to.one]
local Module2 = R[path.to.two]
local Module3 = R[path.to.three]
local Module4 = R[path.to.four]
local Module5 = R[path.to.five]

I understand that saving times to type the codes are important. However, keeping the codes clean, simple, and readable is also important. The way you’re using it is absolutely saves you only a little bit of time only and it’s definitely pointless to do it (Those are my opinion. It doesn’t mean I’m definitely right).

Why use this over just doing the ordinary?;

local moduleOne = require(path.to.module)
local moduleTwo = require(path.to.module)
local moduleThree = require(path.to.module)
local moduleFour = require(path.to.module)

Using the ordinary method, it’s much easier to see what’s what and what to change since it’s sorted.

In my opinion, it looks so much neater instead of;

local Module1,Module2,Module3 = Import(path.to.one,path.to.two,path.to.three)

If you have lots of modules, it’s going to be difficult to find and make edits to the correct path.

Well up to you if you’d rather do your methods instead of using this module. I personally would do the methods you provided instead of using my module as it does seen easier to read, altho less efficient to type.

But in the circumstance of having multiple modules required in one line, I think my module looks more readable than having a bunch of require()'s

1 Like

I believe the issue that’s preventing this module from actually being ‘easier’ and more convenient than multiple require()'s is that this module still depends on paths to the actual moduleScript.

I think you’ll find that migrating from a path-based approach to a name-based approach would make things much more convenient for the user.

i.e
local Module1, Module2, Module3 = Import(“Module1”, “Module2”, “Module3”)

Simply have the import module loop through the game (or a specific container for module scripts) and require the module it finds with the same name. Only issue(?) with this is that all modules must have a unique name.

If you want to go a step further, you can cache each module into the importer as you require it. This way if multiple scripts import the same module, you aren’t looping through to find it every time- you check the cache first and only loop through to find the module if it’s not there.

That aside, being able to import multiple libraries using a single function call is something a few community members would find useful. With a little refining, this could be a nice little module that people use for simplicity’s sake and convenience :+1:

1 Like

Unless you are requiring 8-10 modules in a script, which is problematic as is, I would see no real usage for this.

1 Like