Import - A TypeScript-esque approach to require()

:warning: Warning

This project is more of a proof-of-concept. Its performance does not rival with require() and most likely never will. If you would like to tackle the efficiency and performance be my guest.


What is import?

Import is a TypeScript-esque approach to Roblox’s default require() system. It allows you to use string resolving for path directories, and usage of other shorthand top-level headers.

Documentation

Example

local import = require(game.ReplicatedStorage.Packages.Import)

local Maid = import "@wally/maid" -- handles Wally packages
local SomeClass = import "shared/someClass" -- handles ReplicatedStorage
local SomeClass = import "client/someClass" -- handles LocalPlayer.PlayerScripts
local SomeClass = import "server/someClass" -- handles ServerScriptService

-- for resolving it PascalCase and camelCase are both accepted
local SomeClass = import "shared/SomeClass"

One thing to immediately note is how similar this looks to Rojo’s default file hierarchy. This is intentional as Import is a Wally package itself (hence the need to do ReplicatedStorage.Packages)


Installing Import

Import is a Wally module, and has a GitHub where it can manually installed via .zip file.

Using Wally

[dependencies]
Import = "alexinite/import@0.1.7"
{
    "name": "project-name",
    "tree": {
        "$className": "DataModel",
        "ReplicatedStorage": {
            "$path": "src/shared",
            "Packages": {
                "$path": "Packages"
            },
            "DevPackages": {
                "$path": "DevPackages"
            }
        },
        "ServerScriptService": {
            "$path": "src/server",
            "Packages": {
                "$path": "ServerPackages"
             }
        },
        ...
    }
}

Dot Referencing

Import also allows you to use dot referencing too, but this is where it may become a little weird. Indexing with (script) is only necessary IF you’re going to use dot referencing.

Example

-- indexing [script] here is important: it was either this or getfenv()
local import = require(game.ReplicatedStorage.Packages.Import) (script)

local SomeSubclass = import "./subclass" -- script.Subclass
local ClassInSameDir = import "../otherClass" -- script.Parent.OtherClass

Why not use getfenv()?

getfenv comes with a massive problem: It breaks Luau optimizations. That is the entire reasoning behind why not to use getfenv.


Documentation

@0.1.7 — Updated as of the 2nd of November, 2022

11 Likes

Amazing, Lua will soon be exactly like TypeScript!

2 Likes

v0.1.2 - Now supports Wally DevPackages and ServerPackages!

(see usage) (see issue)

local Maid = import "@wally/maid"
local HttpQueue = import "@wally-server/httpQueue"
local TestEZ = import "@wally-dev/testEZ"

Really cool implementation! Helps a lot with code readability.

Thank you! I’m currently working on making a lot of definitions found in JS/TS into Luau: right now working on Maps and Arrays. I’ve recently published LuaClass which makes classes and class extensions. Also Switch-Case which I won’t make a post about because some has already made that.

Holy! I’ve done something like this earlier based on Python’s but yours clearly has a better syntax than mine imo:

image

Good job!

Also, cool stuffs man, keep 'em up!
Might definitely use this in the future

That’s a pretty interesting syntax you used for yours, may I suggest this?

local message = class(nil, {
    [def "printMessage"] = ...
})

It essentially is the same but seemingly implements “def” as a true method, however what it returns is just “def(printMessage)”. More of a clarity thing.

P.S. I think you’d like a BindSelf method so you can get rid of :'s and instead use .s.

1 Like

Yeah I’ve thought of that at night, too (also I would possibly add staticmethod)

Also, thanks!

Import has been updated! — alexinite/import@0.1.7

Import is now quicker and does not use a metatable to use. This was extremely bad performant-wise. It now is just a function and still supports dot referencing.

Dot Referencing

-- This now doesn't use an `__index` metamethod
local import = require(game.ReplicatedStorage.Packages.Import) (script)

If you use Import, I’d recommend to update to the latest version! Back referencing has also been removed as it frankly didn’t have a reason to exist.