Laravel 9 语言文件目录迁移后失效的解决方案

laravel 9 将语言文件目录从 `resources/lang` 迁移至项目根目录 `lang/`,但若旧目录未彻底清除,框架仍会优先加载 `resources/lang`,导致新路径失效。本文详解迁移要点、排查步骤及最佳实践。

在 Laravel 9 中,语言文件目录的位置变更是一项关键升级改动:官方已将默认语言资源路径从 resources/lang/ 移至项目根目录下的 lang/(即与 app/、config/ 同级)。这一调整简化了资源组织结构,也与 storage/、bootstrap/ 等核心目录层级保持一致。然而,该变更并非“自动切换”——Laravel 的翻译加载器(FileLoader)会按预设顺序搜索多个路径,其中 resources/lang 仍被保留在搜索队列中,且具有更高优先级

这意味着:即使你已将 lang/pt-BR/messages.php 正确放置于项目根目录,并配置了 'locale' => 'pt-BR',只要 resources/lang/ 目录(哪怕为空)依然存在,Laravel 就会首先尝试从此处加载翻译,而忽略根目录的 lang/。这正是你遇到 Lang::get('messages.welcome') 返回字面键 "messages.welcome"(而非翻译值)的根本原因——框架未找到对应翻译项,于是回退到原始键名。

正确迁移步骤如下:

  1. 彻底删除旧目录
    执行以下命令(请确认无误后再操作):

    rm -rf resources/lang

    ⚠️ 注意:仅重命名或清空内容无效,FileLoader 会检测目录是否存在。

  2. 确保新目录结构正确
    根目录下应有:

    your-project/
    ├── lang/
    │   └── pt-BR/
    │       └── messages.php  // 返回 ['welcome' => 'Welcome to the app!']
    ├── app/
    ├── config/
    └── ...
  3. 验证配置与调用
    config/app.php 中保持:

    'locale' => 'pt-BR',

    控制器中使用标准语法(无需更改):

    use Illuminate\Support\Facades\Lang;
    
    return response()->json([
        'message' => Lang::get('messages.welcome'

    ) // ✅ 现在返回 'Welcome to the app!' ]);
  4. 可选:清除配置与视图缓存(升级后推荐执行)

    php artisan config:clear
    php artisan view:clear
    # 若使用了语言包缓存(如 `php artisan lang:publish`),也需清理

? 快速诊断技巧
可通过 dd(app('translator')->getLoader()->getPaths()) 查看当前所有加载路径及其顺序。Laravel 9 默认路径顺序为:

[
  base_path('lang'),      // ← 应该是你的目标路径
  resource_path('lang'),  // ← 必须不存在,否则优先匹配
]

? 总结与建议

  • Laravel 的升级指南强调“移动目录”,但未显式提醒“必须移除旧路径”——这是典型的隐式依赖陷阱;
  • 始终检查 resource_path('lang') 是否真实存在(file_exists(resource_path('lang'))),而非仅依赖 IDE 文件树视觉判断;
  • 新建 Laravel 9 项目能正常工作,正是因为其初始结构本就不含 resources/lang/;
  • 若项目中存在自定义 TranslationServiceProvider 或手动注册 FileLoader,需同步更新路径逻辑。

完成上述清理后,Lang::get()、__() 辅助函数及 Blade 中的 @lang 指令均将无缝支持根目录 lang/ 结构,无需额外配置。