如何在Yarn Berry monorepo中跨包获取i18n JSON文件?
问题背景
使用Yarn Berry Workspace(3.6x版本)配置monorepo,目录结构如下:
pakages └── | i18n | └── locales | ├── en | | └── common.json | └── de | └── common.json sevices └── └── next-js-project
希望仅将语言包(JSON文件)放在packages/i18n中,其余i18n配置在各项目内单独设置,但配置后出现路径错误:
Server Error
Error: Default namespace not found at D:\User\My-monorepo\services\next-js-project@po\i18n\public\locales\en\common.json
错误原因是代码尝试从next-js-project目录下查找语言包,而非指定的packages/i18n路径。
当前配置代码:
next-js-project/next-i18next.config.js
const path = require("path"); module.exports = { i18n: { locales: ["en", "ko"], defaultLocale: "en", localeDetection: false, defaultNS: "common", localePath: path.resolve("@mymonorepo/i18n/locales"), debug: true } };
next-js-project/pages/index.tsx
export const getStaticProps = async ({ locale }) => { console.log("locale", locale); return { props: { ...(await serverSideTranslations(locale, ["common"], nextI18NextConfig)) } }; };
解决方案
1. 修正localePath的路径解析逻辑
path.resolve无法识别Yarn Workspace的模块别名(如@mymonorepo/i18n),必须使用文件系统的绝对路径。由于next-js-project位于services/next-js-project,可以从当前配置文件目录出发,通过相对路径定位到packages/i18n/locales:
修改next-i18next.config.js:
const path = require("path"); module.exports = { i18n: { locales: ["en", "de"], // 与实际locales目录中的语言保持一致,原配置的"ko"不存在 defaultLocale: "en", localeDetection: false, defaultNS: "common", // 从当前文件目录(next-js-project)往上两级到根目录,再进入packages/i18n/locales localePath: path.resolve(__dirname, "../../packages/i18n/locales"), debug: true } };
2. 确认Yarn Workspace基础配置
确保根目录的package.json正确配置了workspaces字段,让Yarn识别所有子项目:
{ "private": true, "workspaces": [ "packages/*", "services/*" ] }
3. 验证路径正确性
可以在配置文件中打印解析后的路径,确认是否指向正确的语言包目录:
const resolvedPath = path.resolve(__dirname, "../../packages/i18n/locales"); console.log("Resolved locale path:", resolvedPath);
关键说明
localePath要求的是文件系统的绝对路径,而非模块别名。Yarn的模块别名属于Node/webpack的模块解析逻辑,path.resolve无法直接解析这类别名,必须通过相对路径结合__dirname(当前文件的目录)来生成正确的绝对路径。
内容的提问来源于stack exchange,提问作者김정수

