Implementing relative require in vanilla Lua is problematic, usually requiring pasting a pattern at the top of each file. It falls apart further when using
init.lua files, requiring different patterns.
LUA_PATH environment variable introduces another layer of configuration complexity and platform compatibility nightmare. Because of these issues, you need layers upon layers of hacks to make the module system convenient. Even when the module system is made convenient, it's hard to tell where modules will be loaded from on any given system executing your code!
Compare the default
package.path across Lua versions:
Creating a package that's compatible with all these is a headache!
Furthermore, if you want to make a package that users can drop into their codebase wherever, you have to resort to crazy pattern matching, like:
local modules = (...):gsub('%.[^%.]+$', '') .. "." local utils = require(modules .. "utils")
(taken from here)
Instead of what you actually want to write:
local utils = import("./utlis")
Some tools try to work around this insanity:
- LuaRock's default paths and setup
Baste is a module system that doesn't have these problems. It also:
- Has no dependencies
- Is simple to use, with no per-file boilerplate
- Can be used for libraries or applications without leaking (no globals by default!)
- Distinguishes relative and absolute imports
- Works predictably in any environment (including Windows!)
- Broad support:
- Lua 5.1, 5.2, 5.3
- LuaJIT 2.0+
- LÖVE 0.10.0+
src/baste.lua somewhere in your project and load it using
baste.import(path) to load your first module. Any modules loaded by Baste will have access to a new function called
import that functions the same way as
Your root module might look like:
local baste = require("baste") -- Load and run `src/main.lua` baste.import("./src/main")
And then in
src/main.lua, you can write code like:
local GameState = import("./GameState") local Something = import("./Entities/Something")
Baste is available under the MIT license. See LICENSE.md for details.