我正在使用 React 制作一个多语言通用应用程序,我很难找到处理语言环境数据的最佳方法。该应用程序将提供 16 种语言版本,并且翻译的消息量非常大,所以我无法将所有消息加载到一个大 json 中(因为它在大多数 react-intl 示例中使用),我不能在 webpack 生成的包中导入这些消息,我只需要按需加载用户语言消息。当应用程序仅在客户端运行时,我能够做到这一点,但我也需要它也可以在服务器端运行。我使用 express 进行服务器端渲染,使用 webpack 进行捆绑。任何人都可以帮助找出解决这个问题的最佳方法吗?
问问题
1991 次
1 回答
4
我最近一直在做类似的事情,尽管我的项目中没有 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");
/***/ })
}]);
希望这可以帮助。祝您项目国际化好运!
于 2019-10-30T00:52:32.777 回答