Lua中如何让require("__base__/bar")指向指定路径?
问题描述
我通过lua foo.lua执行foo.lua文件,文件内包含语句require("__base__/bar"),但bar.lua实际位于C:\Temp路径下(__base__对应该路径)。要求不能修改require("__base__/bar")这行代码,如何让require在加载以__base__开头的模块时自动指向C:\Temp?
我尝试在foo.lua中添加自定义加载器,能打印出正确路径,但仍无法成功加载:
-- foo.lua local function custom_loader(name) -- 把模块名里的"__base__"替换成"C:/Temp" local modified_name = name:gsub("__base__", "C:/Temp") -- 尝试用修改后的名称加载模块 print("DEBUG", package.searchpath(modified_name, "?.lua")) return package.searchpath(modified_name, "?.lua") end table.insert(package.searchers, custom_loader) require("__base__/bar") print("foo")
执行后的错误输出:
PS C:\Users\Daniel\Documents\source\asset> .\lua52.exe .\foo.lua DEBUG: C:/Temp/bar.lua C:\Users\Daniel\Documents\source\asset\lua52.exe: .\foo.lua:10: module '__base__/bar' not found: no field package.preload['__base__/bar'] no file 'C:\Users\Daniel\Documents\source\asset\lua\__base__/bar.lua' no file 'C:\Users\Daniel\Documents\source\asset\lua\__base__/bar\init.lua' no file 'C:\Users\Daniel\Documents\source\asset\__base__/bar.lua' no file 'C:\Users\Daniel\Documents\source\asset\__base__/bar\init.lua' no file '.\__base__/bar.lua' no file 'C:\Users\Daniel\Documents\source\asset\__base__/bar.dll' no file 'C:\Users\Daniel\Documents\source\asset\loadall.dll' no file '.\__base__/bar.dll' no file 'C:\Users\Daniel\Documents\source\asset\__base__/bar52.dll' no file '.\__base__/bar52.dll'C:/Temp/bar.lua stack traceback: [C]: in function 'require' .\foo.lua:10: in main chunk [C]: in ?
问题原因
你的自定义加载器逻辑不符合Lua规范:package.searchpath仅返回文件路径,但package.searchers中的加载器函数需要返回加载模块的执行函数,或返回nil加错误提示字符串。直接返回路径会被Lua判定为无效加载器,进而跳过该逻辑继续使用默认加载器,导致找不到目标模块。
解决方法
修改自定义加载器,找到文件路径后用loadfile生成加载函数并返回,同时处理文件不存在的情况,且优先执行自定义加载器:
-- foo.lua local function custom_loader(name) -- 仅处理以__base__开头的模块,不干扰其他模块加载 if not name:match("^__base__/") then return nil, "not a __base__ module" end -- 替换路径标识与分隔符,拼接完整文件路径 local file_path = name:gsub("__base__", "C:/Temp") .. ".lua" -- 兼容Windows路径分隔符(可选,Lua本身也支持/) file_path = file_path:gsub("/", "\\") -- 尝试加载文件并返回加载函数 local loader_func, err_msg = loadfile(file_path) if loader_func then print("DEBUG: Loading", file_path) return loader_func end -- 加载失败时返回错误信息 return nil, "failed to load: " .. err_msg end -- 将自定义加载器插入到searchers最前端,确保优先执行 table.insert(package.searchers, 1, custom_loader) require("__base__/bar") print("foo")
关键说明
- 优先执行:将加载器插入
package.searchers的第1位,让Lua优先使用自定义逻辑查找模块。 - 模块过滤:通过
name:match("^__base__/")限定仅处理目标模块,避免影响其他正常模块的加载流程。 - 正确返回值:找到文件时返回
loadfile生成的加载函数,加载失败时返回nil加错误信息,完全符合Lua加载器的规范要求。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

