根本原因是sumneko.lua不读取package.path或LUA_PATH,只认.luarc.json中显式配置的runtime.path;需将luarocks安装路径(如C:/Users/name/AppData/Roaming/luarocks/share/lua/5.4/?.lua)加入该字段并重启Lua服务器。

为什么 require "luasocket" 一直标红,但终端里 lua -l luasocket 能跑通
根本原因不是插件没装对,而是 sumneko.lua 语言服务器压根不读你的 package.path 或 LUA_PATH 环境变量。它只认你手动写进 .luarc.json 的 runtime.path 字段——哪怕你在 shell 里 export 了完整路径,它也当没看见。
-
.luarc.json必须放在项目根目录,内容不能是空对象,至少要包含{"runtime.path": ["./?.lua"]} - 如果你用
luarocks install luasocket装到了用户目录(如C:Users ameAppDataRoamingluarockssharelua.4?.lua),就得把这路径显式加进runtime.path数组里 - Windows 下路径里的反斜杠必须双写或改用正斜杠:
"C:\Users\name\AppData\Roaming\luarocks\share\lua\5.4\?.lua"或"C:/Users/name/AppData/Roaming/luarocks/share/lua/5.4/?.lua" - macOS/Linux 用户注意:luarocks 默认安装到
~/.luarocks/share/lua/5.4/?.lua,但 VSCode 启动时可能没继承 shell 的$HOME,建议用绝对路径写死
luarocks 安装的模块在 VSCode 里 require 标红,但运行时又不报错
这是典型“静态分析 vs 运行时”脱节。sumneko.lua 只做静态检查,它找不到模块就标红;而 Lua 解释器实际运行时靠 package.path 加载,只要路径对、文件存在,就能跑通。
- 标红不影响执行,但会掩盖真实语法错误(比如拼错函数名),干扰开发节奏
- 别试图在
settings.json里配lua.diagnostics.globals来绕过——那只是关掉报错,不是解决路径问题 - 如果项目用了多个 luarocks tree(比如系统级 + 用户级 + 项目级),
runtime.path数组里要按查找优先级排序,前面的路径匹配成功就不再往后查 - 验证是否生效:改完
.luarc.json后,必须执行Ctrl+Shift+P→Restart Lua Server,不能只重启 VSCode
如何让 VSCode 和终端共用同一套 luarocks 环境
关键不是“同步路径”,而是让两者都指向同一个物理位置。luarocks 的 config-5.4.lua 里定义的 rocks_trees 是源头,VSCode 的 runtime.path 应该复刻它,而不是反过来。
- 先查清楚 luarocks 实际装在哪:终端运行
luarocks path --bin和luarocks path --share,输出的就是真实路径 - Windows 用户特别注意:
luarocks path输出的路径可能含%APPDATA%,VSCode 不解析这个变量,必须手动展开成完整路径(如C:Users ameAppDataRoamingluarocks...) - 如果用了自定义 rocks tree(比如
rocks_trees = { { name = "project", root = "./luarocks" } }),就在.luarc.json里加"./luarocks/share/lua/5.4/?.lua",且确保该目录下真有luasocket文件夹 - 不要把
package.path复制粘贴进runtime.path—— 里面常含?和!占位符,sumneko.lua 不支持这些语法,只认标准的?.lua和?/init.lua
调试时 require 标红导致断点无法命中
这不是调试器的问题,是语言服务器根本没识别到模块结构,导致跳转、补全、甚至部分断点位置计算失效。比如你在 require "utils.net" 后设断点,sumneko 找不到 utils.net 对应的文件,断点就会“悬空”。
- 即使 launch.json 配置完全正确,
program指向的脚本能正常运行,断点也可能不生效——因为语言服务器没加载模块定义 - 检查
.luarc.json是否漏了src/?.lua这类业务代码路径,和 luarocks 的share路径是两回事,必须都写进去 - 如果项目依赖 C 模块(如
luasocket.core),runtime.path里加share路径没用,sumneko.lua 不处理package.cpath,标红可以忽略,只要运行时不报module not found就行 - 最保险的做法:在
.luarc.json里把所有可能用到的路径列全,哪怕暂时没用到,避免后期加新库时反复折腾


















