使用 i18next 进行反应生产构建会导致翻译仅显示字符串

Posted

技术标签:

【中文标题】使用 i18next 进行反应生产构建会导致翻译仅显示字符串【英文标题】:Using i18next for a react production build causes the translation to display only strings 【发布时间】:2021-04-02 11:55:02 【问题描述】:

我相信我已经搜索了互联网的所有部分以寻找答案和修复,但似乎没有一个有效。

问题:

在为生产环境构建使用 i18n 作为翻译的 React 应用程序时,将导致生产环境仅显示字符串作为结果,而不是翻译文本本身(参见图片参考)

奇怪的是,当开发服务器运行时,在本地主机内它会正确显示翻译。 (参考图片)

构建生产版本后,在浏览器控制台内(使用 chrome)显示以下错误:Fetch API cannot load file:///Documents/streaming_site/build/static/locales/en/translation.json. URL scheme must be "http" or "https" for CORS request.

看到这个错误后,我立即假设它是在我的i18next.js 文件中导致了这个问题。这是文件:

import i18n from 'i18next';
import  initReactI18next  from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import XHR from 'i18next-xhr-backend';

// don't want to use this?
// have a look at the Quick start guide 
// for passing in lng and translations on init

const Languages = ['en', 'fr'];

i18n
  .use(XHR)
  // load translation using http -> see /public/locales (i.e. https://github.com/i18next/react-i18next/tree/master/example/react/public/locales)
  // learn more: https://github.com/i18next/i18next-http-backend
  .use(Backend)
  // detect user language
  // learn more: https://github.com/i18next/i18next-browser-languageDetector
  .use(LanguageDetector)
  // pass the i18n instance to react-i18next.
  .use(initReactI18next)
  // init i18next
  // for all options read: https://www.i18next.com/overview/configuration-options
  .init(
    lng : 'en',
    react:  
      useSuspense: false,
      wait: true
    ,
    fallbackLng: 'en',
    debug: false,
    whitelist: Languages,
    interpolation: 
      escapeValue: false, // not needed for react as it escapes by default
    ,
    nsSeperator : false,
    keySeperator : false,
    backend:
      loadPath: () => 

        var cors = require('cors');
        var app = cors();
        
        // check the domain
        const host = window.location.host;
        return (host === 'index.html#' ? '':'') + '/static/locales/lng/ns.json';
      ,
    
  );


export default i18n;

此外,在我的index.js 文件中,我添加了这些额外的修复程序,以确保应用程序能够在生产版本中正确显示翻译后的文本:

i18next.init(// <-- This was added
  interpolation: escapeValue: false,
);
i18next.init().then(() => // <-- This was added
  ReactDOM.render(
    <React.StrictMode>
    <Suspense fallback=<div>Loading...</div>>// <-- This was added
      <I18nextProvider i18n=i18next>// <-- This was added
        <App />
      </I18nextProvider>
    </Suspense>
    </React.StrictMode>,
    document.getElementById('root')
  )
);

唉,在发出npm run build 后出现同样的错误(从第三点开始)

这让我相信,如果没有后端服务器托管 en 和 fr 的 translation.json 文件,就不可能在本地访问它们。

我的问题如下:是否可以在构建生产版本后在本地运行 i18n 翻译而不需要服务器来托管 json 文件?如果是,我将如何进行?

对于参考,我尝试了该网站的一些修复,例如:

    React i18next Backend-Path different in local and production environment

    react-i18next doesn't translate

    Allow Access-Control-Allow-Origin header using HTML5 fetch API

当我尝试时,我已经接近了 --> res.header('Access-Control-Allow-Origin', "*"); 尽管它是以提出一些安全问题为代价的,我不希望这样。虽然如果这是一个潜在的解决方案,我愿意尝试。

所以我在这里没有想法......:/

【问题讨论】:

【参考方案1】:

看起来 i18next 服务配置有误。

首先,i18next-http-backend & i18next-xhr-backend 正在解决同样的问题,获取 json 文件。

删除第二个 (i18next-xhr-backend),因为它已被 i18next-http-backend 弃用。

backend.loadPath 更改为字符串,您的代码没有意义。

它应该看起来像:

import i18n from 'i18next';
import  initReactI18next  from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

// don't want to use this?
// have a look at the Quick start guide
// for passing in lng and translations on init

const Languages = ['en', 'fr'];

i18n
  .use(Backend)
  // detect user language
  // learn more: https://github.com/i18next/i18next-browser-languageDetector
  .use(LanguageDetector)
  // pass the i18n instance to react-i18next.
  .use(initReactI18next)
  // init i18next
  // for all options read: https://www.i18next.com/overview/configuration-options
  .init(
    lng: 'en',
    react: 
      useSuspense: false,
      wait: true,
    ,
    fallbackLng: 'en',
    debug: false,
    whitelist: Languages,
    interpolation: 
      escapeValue: false, // not needed for react as it escapes by default
    ,
    nsSeperator: false,
    keySeperator: false,
    backend: 
      loadPath: '/locales/lng/ns.json',
    ,
  );

export default i18n;

【讨论】:

感谢您的修复,但是当我尝试创建新产品时,在 Chrome 中构建调试控制台时会显示相同的问题:Fetch API cannot load file:///Users/user/Documents/streaming_site/build/static/locales/en/translation.json. URL scheme must be "http" or "https" for CORS request.imgur.com/a/D3CFiBZ 所以应用程序可以毫无问题地找到 json,但是由于此错误,chrome 拒绝加载它。我还尝试了其他浏览器,例如 Safari,也出现了同样的问题。 应用程序的午餐如何? 我只是将 index.html 拖放到 Chrome 中或执行open with &gt; Chrome 所以这是您的问题,因为您以file:// 协议打开 index.html 文件。这不允许您发出 Ajax 请求。您需要使用某些服务器来提供 html 文件,(例如 webpack-dev-server 在开发时提供您的文件)

以上是关于使用 i18next 进行反应生产构建会导致翻译仅显示字符串的主要内容,如果未能解决你的问题,请参考以下文章

i18next 没有加载翻译文件

i18next 不能在 Cordova iOS 6.1.0 上翻译

如何使用 i18next?翻译问题

使用 i18next(占位符,值)翻译自定义属性

如何使用钩子在反应 i18next 中修复“未指定回退 UI”

i18next 在没有翻译文件时得到 404 响应