简体   繁体   English

Webpack动态导入.json文件?

[英]Webpack dynamic import .json file?

I'm using React Intl for x number of languages (example below) and at the moment Im importing the following where I setup my App:我将 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
}

Since these language files are being imported no matter which language is being used my main bundle js file is getting pretty big, especially from the.json files.由于无论使用哪种语言都会导入这些语言文件,因此我的主捆绑 js 文件变得非常大,尤其是来自 .json 文件。

How can I with Webpack split these language files (or copy them to my dist folder using CopyWebpackPlugin) and then dynamically import them based on the language being used at the moment?如何使用 Webpack 拆分这些语言文件(或使用 CopyWebpackPlugin 将它们复制到我的 dist 文件夹),然后根据当前使用的语言动态导入它们?

The app is isomorphic so this same code is being run on the server.该应用程序是同构的,因此相同的代码正在服务器上运行。

I've been working on something like this lately, although I don't need SSR for my project.我最近一直在做类似的事情,尽管我的项目不需要 SSR。 I found that pairing dynamic import syntax with React's Suspense component achieves the desired result.我发现将动态导入语法与 React 的 Suspense 组件配对可以达到预期的效果。 Here's a rough overview of what I found to work, at least in my case, which doesn't include SSR:这是我发现的工作的粗略概述,至少在我的情况下,其中不包括 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 should split each locale JSON file into its own chunk. Webpack 应该将每个语言环境 JSON 文件拆分为自己的块。 If it doesn't, something is likely transpiling the dynamic import syntax to a different module system (require, etc) before it reaches webpack.如果没有,则可能在动态导入语法到达 webpack 之前将其转换为不同的模块系统(require 等)。 For example: if using Typescript, tsconfig needs "module": "esnext" to preserve import() syntax.例如:如果使用 Typescript,tsconfig 需要"module": "esnext"来保留import()语法。 If using Babel, it may try to do module transpilation too.如果使用 Babel,它也可能会尝试进行模块转译。

The chunk output for a single locale will look something like this;单个语言环境的块 output 看起来像这样; definitely more than would be achieved via CopyWebpackPlugin:绝对比通过 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");

/***/ })

}]);

Hopefully, this is a good starting point and either works with SSR or can be modified to work with SSR.希望这是一个很好的起点,可以与 SSR 一起使用,也可以修改为与 SSR 一起使用。 Please report back with your findings on that subject.请报告您在该主题上的发现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM