我正在将 React Intl 用于 x 种语言(下面的示例),目前我在设置应用程序的位置导入以下内容:

import { addLocaleData } from 'react-intl';
import locale_en from 'react-intl/locale-data/en';
import locale_de from 'react-intl/locale-data/de';

import messages_en from './translations/en.json';
import messages_de from './translations/de.json';

addLocaleData([...locale_en, ...locale_de]);

...
export const messages = {
    en: messages_en,
    de: messages_de
}

由于无论使用哪种语言都会导入这些语言文件,因此我的主包 js 文件变得非常大,尤其是来自 .json 文件。

如何使用 Webpack 拆分这些语言文件(或使用 CopyWebpackPlugin 将它们复制到我的 dist 文件夹),然后根据当前使用的语言动态导入它们?

该应用程序是同构的,因此相同的代码正在服务器上运行。

#1楼 票数:0

我最近一直在做这样的事情,虽然我的项目不需要 SSR。 我发现将动态导入语法与 React 的 Suspense 组件配对可以达到预期的效果。 这是我发现的工作的粗略概述,至少在我的情况下,其中不包括 SSR:

// wrap this around your JSX in App.js:
<React.Suspense fallback={<SomeLoadingComponent />}>
  <AsyncIntlProvider>
    {/* app child components go here */}
  </AsyncIntlProvider>
</React.Suspense>

// the rest is in support of this
// can be placed in another file
// simply import AsyncIntlProvider in App.js

const messagesCache = {};

const AsyncIntlProvider = ({ children }) => {
  // replace with your app's locale getting logic
  // if based on a hook like useState, should kick off re-render and load new message bundle when locale changes (but I haven't tested this yet)
  const locale = getLocale();

  const messages = getMessages(locale);
  return (
    <IntlProvider locale={locale} messages={messages}>
      {children}
    </IntlProvider>
  );
};

function getMessages(locale) {
  if (messagesCache[locale]) {
    return messagesCache[locale];
  }
  // Suspense is based on ErrorBoundary
  // throwing a promise will cause <SomeLoadingComponent /> to render until the promise resolves
  throw loadMessages(locale);
}

async function loadMessages(locale) {
  // dynamic import syntax tells webpack to split this module into its own chunk
  const messages = await import('./path/to/${locale}.json`);
  messagesCache[locale] = messages;
  return messages;
}

Webpack 应该将每个语言环境 JSON 文件拆分为自己的块。 如果没有,则可能在动态导入语法到达 webpack 之前将其转换为不同的模块系统(require 等)。 例如:如果使用 Typescript,tsconfig 需要"module": "esnext"以保留import()语法。 如果使用 Babel,它也可能会尝试进行模块转译。

单个语言环境的块输出看起来像这样; 绝对比通过 CopyWebpackPlugin 实现的要多:

(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{

/***/ "./path/to/en-US.json":
/*!*************************************!*\
  !*** ./path/to/en-US.json ***!
  \*************************************/
/*! exports provided: message.id, default */
/***/ (function(module) {

eval("module.exports = JSON.parse(\"{\\\"message.id\\\":\\\"Localized message text\\\"}\");//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvbG9jYWxpemF0aW9uL2VuLVVTLmpzb24uanMiLCJzb3VyY2VzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./path/to/en-US.json\n");

/***/ })

}]);

希望这是一个很好的起点,可以与 SSR 一起使用,也可以修改为与 SSR 一起使用。 请报告您在该主题上的发现。 🙂

  ask by nickelman translate from so

未解决问题?本站智能推荐:

1回复

React-Router和React-Intl:是否有更好的方法来动态加载翻译的路由?

当页面的路线更改时,我将动态加载页面的翻译。 我为每个路由使用了onEnter。 有没有更好的方法来实现这一目标? 我可以避免对每个路由使用onEnter回调函数吗?
1回复

使用Webpack 1构建时,使用react-intl消息呈现反斜杠

摘要 当我使用Webpack Dev Server加载我的应用程序时,我的消息显示正常: \\ 。 但是当我将应用程序捆绑到磁盘并通过nginx服务器捆绑包时,我看到我的反斜杠重复: \\\\ 。 细节 我正在使用react-intl @ 2.2.3(此时最新)和bab
1回复

动态导入react / react-intl的语言json文件

这是我配置客户端通过react-intl呈现正确语言的方式。 但是我想根据cookie中的语言环境动态导入localeData。 因此,如果我的用户的语言环境是“en”,我将只加载en.json文件。 这样做的正确方法是什么? 尝试创建一个函数,但我无法正确地将数据传递给消息
1回复

带有路由的Webpack生产版本无法加载1.bundle.js文件

我有一个针对此问题的测试仓库( Link ) 我认为这是本地化文件的问题。 我使用react-intl。 开发版本效果很好。 问题是: 创建生产版本 运行生产服务器 打开应用程序http:// localhost:3001 / activities
1回复

如何使用react_intl将语言文件数据动态导入到我的APP.js中

我需要将index.js中所选语言的数据导入到app.js中 我的index.js 和我的app.js 还有我的en.js 我没有从App.js按钮中的语言文件中获取数据。 您能否在这方面帮助我/请尽可能更正我的代码
1回复

react-intl,异步转换导入和SSR

我有一个React应用程序,它使用react-intl来提供翻译,并且它适用于浏览器DOM渲染。 我有一个组件,它使用import()处理基于它接收的道具的异步语言环境/翻译,然后一旦加载语言环境+翻译数据,就会呈现<IntlProvieder> 。 像这样: 但是,当
1回复

react-intl:TypeError:如果使用嵌套的json消息,则必须以String或AST的形式提供消息

当将react-intl与嵌套的json消息一起使用时,我在控制台中看到错误: 但是UI正常工作。 ¯\\ _(ツ)_ /¯ 消息(en.json) { "App.folderChooser.text": "Select folder to parse", "App.f
3回复

如何使用 FormatJS CLI 从多个特定文件夹中提取消息?

我有/components/foo.js和/pages/bar.js ,两者都使用<FormattedMessage />和不同的defaultMessage : 如果我运行formatjs extract 'components/**/*.js' --out-file lang/e