$ luarocks install importutilsA modern, feature-rich module loading system for Lua
importutils is an enhanced module loader that extends Lua's standard require with powerful features including relative imports, asynchronous loading, dependency tracking, and hot reloading. It provides a more intuitive and developer-friendly way to manage modules in Lua projects.
Key Features
Relative Imports
Import modules relative to the current file, eliminating the need to manipulate package.path manually:
```lua
-- In /project/src/main.lua
local helper = import("./utils/helper") -- Relative to current file
local config = import("../config") -- Parent directory
local deep = import("./sub/module/deep") -- Deep nesting
```
Asynchronous Loading
Load multiple modules in parallel without blocking execution, significantly reducing startup time:
```lua
-- Load modules concurrently
local result = import.async("database", "cache", "logger")
result:as("db", "cache", "log") -- All modules load in parallel
-- With completion callback
import.async(function(err, modules)
if not err then
print("All modules loaded successfully")
end
end, "module1", "module2")
```
Directory Import with Wildcards
Load all Lua files from a directory with a single statement:
```lua
-- Load all handlers from the handlers/ directory
local handlers = import("handlers.*")
-- Returns: {auth = auth_module, user = user_module, ...}
-- With alias
local h = import("handlers.*"):as("h")
```
Alias System
Clean and readable alias assignment for multiple imports:
```lua
-- Single module alias
local log = import("logger"):as("log")
-- Multiple module aliases
local utils, config, db = import("utils", "config", "database"):as("u", "c", "db")
-- Directory import with alias
local h = import("handlers.*"):as("h")
```
Smart Path Resolution
Intelligent path resolution with automatic normalization across platforms:
```lua
-- All of these work consistently
import("utils.string") -- Standard dotted notation
import("./local/helper") -- Relative path
import("../parent/module") -- Parent directory
import("../../deep/nested") -- Multiple levels up
import("utils\\string") -- Windows style (auto-converted)
```
Hot Reload
Reload modules at runtime without restarting your application, ideal for development:
```lua
-- Reload all modules
libmodules.reload(true) -- Preserve global variables
libmodules.reload(false) -- Clean reload
-- Check what's currently loaded
local loaded = libmodules.list()
```
Dependency Analysis
Automatic dependency tracking with circular dependency detection:
```lua
-- Get module dependencies
local deps = libmodules.packages("main")
-- Build dependency tree
local tree = libmodules.deps_tree("main")
-- Throws error if circular dependency is detected
-- List all loaded modules with metadata
local loaded = libmodules.list()
```
Existence Checking
Check if a module exists before attempting to load it:
```lua
if libmodules.exist("optional_module") then
local mod = import("optional_module"):as("opt")
end
```
Enhanced Error Handling
Detailed error messages with context for easier debugging:
```lua
-- Clear error with context
import("nonexistent")
-- Error: [libmodules] Failed to load module (module: nonexistent) (path: nonexistent.lua)
import("a", "b"):as("x")
-- Error: [libmodules] Alias count mismatch (expected: 2) (got: 1)
```
Quick Examples
Basic Project Setup
```lua
-- main.lua
local import = require("importutils")
-- Load project modules
local config = import("config"):as("c")
local utils = import("utils.*")
local handlers = import("handlers.*"):as("h")
-- Use loaded modules
local app = handlers.app
app.run(config)
```
Development Workflow
```lua
-- development.lua
local import = require("importutils")
-- Load and reload during development
local function dev_loop()
while true do
libmodules.reload(true)
local app = import("app"):as("app")
app.start()
-- Wait for file changes, then repeat
end
end
```
Plugin System
```lua
-- plugin_loader.lua
local import = require("importutils")
-- Load all plugins dynamically
local plugins = import("plugins.*")
for name, plugin in pairs(plugins) do
if plugin.enabled then
plugin.init()
end
end
```
Requirements
· Lua 5.2+ or LuaJIT 2.1+ (with 5.2 compatibility)
· Optional: luafilesystem (lfs) for enhanced file operations
· Optional: cqueues or llthreads for asynchronous loading