起因

同事写了行加载模块的代码,在 PC 上可以加载得到,在真机上却不行。于是我猜可能是因为查找路径有什么差异。

​local Bitmap = require"Assets.Lua.game.modules.helper.common.Bitmap"​

解决

因为打包时,会把 Lua 目录下的文件另外打包放在工程外,因此真机运行时,Lua 就是根目录(加载模块时,会搜索根目录是否有这个 lua 文件),并没有 Assets/Lua 这层目录关系,自然也就加载不到了。路径改成 ​​.game.modules.helper.common.Bitmap​​ 即可。

延展

Lua 通过 require 全局函数来加载模块。

require 加载过程


  • 查找全局缓存表 package.loaded[modname] 。所有加载过的模块都会被保存在这个表里,避免重复加载。
  • 通过 package.searchers 查找加载器并调用加载。除了 package.preload 不回返回值意外,其他加载器都会返回找到的模块的文件名。

  1. package.preload[modname] 中查找加载器。
  2. 使用存储在 package.path 中的路径来查找 Lua 模块。这个路径是一个用分号分隔的模板构成的字符串。把模板中的问号替换成 modname替换为系统的目录分隔符
  3. 使用存储在 package.cpath 中的路径来查找 C库
  4. 一体化加载器。从 C 路径中查找指定模块的根名字。


Lua 运行时热重载

大体就是重新加载模块(​​package.loaded[modname] = nil​​),替换旧模块的成员,数据保留,方法替换(替换前要通过 ​​debug.setupvalue debug.getupvalue​​将旧方法的 ​​upvalue​​ 取出复制到新方法中)。