React Intl:异步加载通用应用程序中的一个特定区域设置数据

时间:2016-08-30 13:50:40

标签: reactjs internationalization webpack react-intl

我正在使用React创建一个多语言通用应用程序,我很难找到处理区域设置数据的最佳方法。 该应用程序将以16种语言提供,翻译的消息量非常大,因此我无法在一个大json中加载所有消息(因为它在大多数react-intl示例中使用)而且我不能在webpack生成的bundle中导入这些消息,我只需要按需加载用户语言消息。 当应用程序刚刚在客户端运行时,我能够做到这一点,但我也需要它在服务器端工作。我正在使用express用于服务器端渲染和webpack进行捆绑。任何人都可以帮忙找出解决这个问题的最佳方法吗?

1 个答案:

答案 0 :(得分: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 something like useState, should kick off re-render and load new message bundle when locale changes
  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,它可能也会尝试进行模块移植。

单个语言环境的块输出看起来像这样:

(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");

/***/ })

}]);

希望这会有所帮助。祝您国际化,使您的项目国际化! ?