我正在使用x种语言的React Intl (示例如下),目前我正在导入以下设置我的应用程序的位置:
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文件夹中),然后根据当前使用的语言动态导入它们?
这个应用程序是同构的,所以同样的代码也在服务器上运行。
发布于 2019-11-07 06:26:27
我最近一直在做这样的事情,尽管我的项目不需要SSR。我发现将动态导入语法与React的悬念组件配对可以达到预期的效果。下面是我发现的工作原理的大致概述,至少在我的例子中是这样的,其中不包括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一起工作。请将您对该主题的调查结果反馈给我们。?
https://stackoverflow.com/questions/58001506
复制相似问题