使用 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 > Chrome
所以这是您的问题,因为您以file://
协议打开 index.html 文件。这不允许您发出 Ajax 请求。您需要使用某些服务器来提供 html 文件,(例如 webpack-dev-server 在开发时提供您的文件)以上是关于使用 i18next 进行反应生产构建会导致翻译仅显示字符串的主要内容,如果未能解决你的问题,请参考以下文章
i18next 不能在 Cordova iOS 6.1.0 上翻译