path
package.path
和package.cpath
中, 保存了lua的文件路径模版, 在执行require
时, 会将参数带入到模板中查找加载文件
文件加载策略
- 查找
package.loaded
表, 检测文件是否已经被加载, 如果已经被加载, 则直接返回已被加载到内存中的数据 - 在
package.searchers
中总共有4个加载器, 分别是 预加载器 lua加载器 c加载器 一体化加载器, require也按照顺序来执行加载器。找到了就成功返回,没有就继续查找 - 加载文件的过程中, 会将路径模板中的
?
替换为文件名, 例如, 模板为C:\lua-5.3.6\bin\lua\?.lua;C:\lua-5.3.6\bin\lua\?\init.lua;C:\lua-5.3.6\bin\?.lua;C:\lua-5.3.6\bin\?\init.lua;C:\lua-5.3.6\bin\..\share\lua\5.3\?.lua;C:\lua-5.3.6\bin\..\share\lua\5.3\?\init.lua;.\?.lua;.\?\init.lua;
, 在require("main")
时, 会依次尝试打开C:\lua-5.3.6\bin\lua\main.lua;C:\lua-5.3.6\bin\lua\main\init.lua;C:\lua-5.3.6\bin\main.lua;C:\lua-5.3.6\bin\main\init.lua;C:\lua-5.3.6\bin\..\share\lua\5.3\main.lua;C:\lua-5.3.6\bin\..\share\lua\5.3\main\init.lua;.\main.lua;.\main\init.lua;
, 加载动态库文件时也是同理
加载成功后处理
加载文件成功后, package.loaded
中会记录该模块, 下次require时, 就会直接使用loaded
中的数据
重写require实现lua环境修改功能
在require时, 如果需要修改_ENV, 可以通过重写require函数来实现, 具体实现细节如下:
1 | local require = function (name, mode, env) |