如何组织Lua模块路径并编写“require”调用而不失灵活性?
假设我有一个项目,其文件夹结构如下:
| main.lua
|
|---<model> // 这是一个文件夹
| |a.lua
| |b.lua
|
|---<view>
|a.lua
|b.lua
model/a.lua 要求 model/b.lua: require "b"
view/a.lua 要求 view/b.lua: require "b"
main.lua 要求 model 和 view 中的文件。
现在我有问题,无法正确加载这些模块。我知道可以通过更改 require 调用来解决:
model/a.lua:require "model.b"
view/a.lua:require "view.b"
但如果我这样做,每次更改文件夹结构时都必须修改这些文件。
所以我的问题是:
- 如何在不在模块文件中硬编码路径的情况下解决模块路径问题?
- 为什么 Lua 没有使用 Node.js 的模块搜索规则,看起来更容易一些?
你可以使用一些方法。
你可以添加相对路径到package.path,就像这个SO回答中所示。在你的情况下,你需要在main.lua中添加路径,这些路径对应于你可能访问文件的各种方式。这样做可以将所有更改限制在一个文件范围内,以便在更改目录结构时,只需修改一个文件。
你可以使用debug.getinfo添加绝对路径到package.path -- 这可能会更加容易,因为你不需要考虑相对路径访问,但是你仍然需要在更改目录结构时在main.lua中进行此操作,并且需要对debug.getinfo返回的值进行字符串操作以去掉模块名称并添加子目录名称。
> lunit = require "lunit"
> info = debug.getinfo(lunit.run, "S")
> =info.source
@/usr/local/share/lua/5.2/lunit.lua
> =info.short_src
/usr/local/share/lua/5.2/lunit.lua
当您 require 一个模块时,require 命令中的字符串参数传递给该模块,您可以使用变量参数语法 ... 访问它。您可以使用这种方法来包含其他依赖模块,这些模块与当前模块在 相同的路径 中而无需使其依赖于一个固定的硬编码模块名称。
例如,您可以这样做:
-- model/a.lua
local thispath = select('1', ...):match(".+%.") or ""
require(thispath.."b")
和
-- view/a.lua
local thispath = select('1', ...):match(".+%.") or ""
require(thispath.."b")
现在,如果更改目录结构,例如将 view 移动到例如 control/subcontrol/foobar,则 control/subcontrol/foobar/a.lua(原来是 view/a.lua)现在将尝试要求 control/subcontrol/foobar/b.lua,从而“ _做正确的事情_”。
当然,main.lua 仍然需要完全限定路径,因为您需要一种方法来消除 model/a.lua 和 view/a.lua 之间的歧义。
解决方法是将main.lua文件夹(项目根目录)添加到main.lua中的package.path中。
一种支持一级深度文件夹的幼稚方法:
-- main.lua
package.path = package.path .. ";../?.lua"
注意,在(项目根目录)中使用的
require函数将在项目根目录之外查找文件,这是不可取的。
更好的方法是使用一些库(如:[paths](https://github.com/torch/paths),“penlight”)解析绝对路径并将其添加:
-- main.lua
local projectRoot = lib.abspath(".")
package.path = package.path .. ";" .. projectRoot .. "/?.lua"
然后在源中使用文件夹名称来作用域文件:
-- model/a.lua
require "model.b"
-- 你甚至可以这样做
require "view.b"
和
-- view/a.lua
require "view.b"
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
如何在模块文件中不硬编码路径的情况下解决模块路径问题?
我没有更好的跨平台解决方案,也许你应该早期规划文件夹结构。
为什么 Lua 不使用 Node.js 的模块搜索规则,看起来更容易?
因为 Lua 尽最大努力依赖于 ANSI C,这非常成功。在 ANSI C 中,没有目录的概念。