【问题标题】:Is there any way to access `__filename` in Next.js?有什么方法可以访问 Next.js 中的`__filename`?
【发布时间】:2021-07-18 10:20:18
【问题描述】:

我正在开发一个自定义 i18n 模块,并希望替换此代码(这是一个“关于我们”页面):

  const messages = (await import(`./about-us.${locale}.json`))
    .default as Messages;

  const messages = (
    await import(`./${__filename.replace('.tsx', `.${locale}.json`)}`)
  ).default as Messages;

不幸的是,__filename 解析为/index.js(我猜是因为 Webpack?) - 有什么方法可以实现我在示例中尝试做的事情,或者这需要直接内置在 Next.js 中工作吗?

【问题讨论】:

  • 停止打包你的节点代码。只对 browserland 代码进行 webpack。
  • 我不能用 Next.js :) 如果你想看看我在说什么,请查看我的评论。

标签: javascript node.js reactjs typescript next.js


【解决方案1】:

重构这个,让消费者不知道文件系统

剧透:我不会告诉你如何使用 Next.js 访问 __filename;我对此一无所知。

这是一个比您建议的更好的模式,并且完全回避了问题。

首先,设置:听起来您有一个文件夹,里面装满了这些 JSON 文件。我想这个:

l10n/
    about-us.en-US.json
    about-us.fr-FR.json
    contact-us.en-US.json
    contact-us.fr-FR.json
    ... <package>.<locale>.json

这种文件组织很好,但让每个潜在的 l10n 消费者都知道它是一个错误。

  • 如果您稍后更改命名方案怎么办?您是否要手动编辑每个导入本地化文本的文件?你为什么要对未来你这么差?
  • 如果特定的语言环境文件不存在,您是希望应用崩溃,还是退回到其他语言?1

最好创建一个以packageNamelocaleCode 作为参数并返回所需内容的函数。然后,该函数成为应用程序中唯一需要了解文件名、回退逻辑等的部分。

// l10n/index.js
export default function getLang( packageName, localeCode ) {
    let contentPath = `${packageName}.${localeCode}.json`
    // TODO: fallback logic
    return JSON.parse(FS.readFileSync(contentPath, 'utf8'))
}

定位和读取所需数据是一项复杂的工作,同时还要确保没有任何请求永远获得空负载并且每个文本键都解析为一个值。动态 import + 健全的文件系统是一个好的开始(:掌声:),但这种组合本身还不够强大。

在之前的工作中,我们构建了一个完整的微服务只是为了做这件事。 (我们还构建了一个单独的服务来获取翻译,以及一些私有 npm 包以允许 web 应用程序从我们的 CMS 请求和使用语言包。)你不必走那么远,但它希望能说明问题空间并不小。


1 后备逻辑:例如en-UK & en-US 通常可以互换;在紧急情况下,一些罗曼语组可能是可以接受的(想到西班牙语/葡萄牙语/巴西语);还有日耳曼语等。什么有效,什么不取决于内容和上下文,但没有任何版本的回退适合动态import

【讨论】:

  • 我要 +1 你的答案,因为它背后的辛勤工作,事实上它是正确的,但它不适用于 Next.js,因为可能是 Webpack。这就是为什么我很可能会研究 Webpack 加载器(如 CSS 模块)的原因——我梦想有一个解决方案,其中字符串位于页面或组件旁边。如果您想查看工作原型:github.com/Avansai/next-intl-routes
【解决方案2】:

经过长时间的搜索,解决方案是编写一个 useMessages 钩子,使用自定义 Babel 插件“注入”正确的字符串。

Webpack 加载器似乎不是正确的选择,因为加载器只能访问它加载的文件的内容。通过使用 Babel,我们有更多的选择可以将代码注入到最终编译的版本中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多