Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Neovim Lua 模块缓存问题

问题表现

启动 Neovim 时,LSP 配置加载失败,报错如下:

Failed to load `plugins.lsp.lspconfig`

... module 'config.lsp.vuels' not found:
    no field package.preload['config.lsp.vuels']
    cache_loader: module 'config.lsp.vuels' not found
    cache_loader_lib: module 'config.lsp.vuels' not found

关键特征:

  • 错误指向的模块名(vuels)与实际配置中的内容(vtsls)不符
  • 使用了 Nix + Home Manager 管理 Neovim 配置

根本原因

Neovim 的 Lua 字节码缓存(.luac 文件)未正确刷新,导致加载了旧的编译结果。

LuaJIT/Lua 5.1 缓存机制

  • Neovim 使用 LuaJIT 或 Lua 5.1
  • 为加速启动,将 Lua 文件编译为字节码缓存到 ~/.cache/nvim/luac/
  • 缓存文件名经过 URL 编码

Nix 符号链接的复杂性

  • 配置文件通过符号链接指向 Nix Store
  • 当 Nix Store 路径变化时,缓存可能指向旧位置
  • 文件内容变化但路径不变时,缓存检测机制可能失效

排查思路

第一步:验证配置文件内容

cat ~/.config/nvim/lua/config/lsp/init.lua

确认文件内容正确(如第 18 行应为 vtsls 而非 vuels)。

第二步:检查 Nix Store 中的文件

cat /nix/store/...-hm_conf/lua/config/lsp/init.lua

确认 Nix Store 中的文件也是正确的。

第三步:定位缓存问题

ls ~/.cache/nvim/luac/

缓存目录存在大量 .luac 文件,即使源文件已更新,缓存可能未同步刷新。

第四步:确认缓存机制

错误信息中 cache_loader: module 'config.lsp.vuels' not found 表明缓存系统参与了加载过程,加载了过期的字节码。

解决方案

快速解决(推荐)

# 清除 Lua 字节码缓存
rm -rf ~/.cache/nvim/luac

# 重启 Neovim
nvim

进阶解决

# 1. 清除所有 Neovim 缓存
rm -rf ~/.cache/nvim/

# 2. 清除 lazy.nvim 插件缓存(会重新下载插件)
rm -rf ~/.local/share/nvim/lazy/

# 3. 重启 Neovim
nvim

彻底清除(最后手段)

rm -rf ~/.cache/nvim/
rm -rf ~/.local/share/nvim/
rm -rf ~/.local/state/nvim/
nvim

预防措施

Home Manager 激活脚本

在 Nix 配置中添加自动清除缓存的激活脚本:

home.activation.clearNvimCache = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
  rm -rf "${config.home.homeDirectory}/.cache/nvim/luac"
'';

Shell 别名

alias nvim-clean='rm -rf ~/.cache/nvim/luac && nvim'

常见场景速查

场景症状解决方法
修改 Lua 配置后未生效配置更改但行为不变rm -rf ~/.cache/nvim/luac
移动/重命名 Lua 模块模块找不到错误rm -rf ~/.cache/nvim/luac
Nix 配置切换后异常插件加载失败、配置混乱rm -rf ~/.cache/nvim/
插件更新后出错插件功能异常、报错rm -rf ~/.local/share/nvim/lazy/
完全混乱无法启动多种错误交织彻底清除所有缓存

技术细节

缓存文件命名

缓存文件名是原始路径的 URL 编码:

  • 原始路径:/Users/moonshot/.config/nvim/lua/config/lsp/init.lua
  • 缓存名:%2fUsers%2fmoonshot%2f.config%2fnvim%2flua%2fconfig%2flsp%2finit.luac

加载优先级

  1. package.preload — 预加载表
  2. cache_loader — 字节码缓存加载器
  3. cache_loader_lib — 库缓存加载器
  4. 文件系统搜索 — 原始 .lua 文件

错误信息中的顺序反映了 Neovim 的模块加载尝试顺序。

参考信息

目录说明
~/.cache/nvim/luac/Lua 字节码缓存
~/.local/share/nvim/lazy/lazy.nvim 插件目录
~/.local/state/nvim/LSP 日志等状态文件
相关技术LuaJIT, Lua 5.1, Nix, Home Manager