Исключите файлы JSON из основного комплекта с помощью веб-пакета для реакции-лотереи - PullRequest
0 голосов
/ 02 ноября 2018

В нашем веб-приложении у нас есть несколько JSON-файлов по ~ 10-80 тыс. Строк каждый. Они включены в наш основной комплект. Они используются плагином анимации под названием Reaction-Lottie.

Пример нашего webpack.config.js

module.exports = {
  entry: ["./src/index.js"],
  module: {
    rules: [
      { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ["babel-loader"] },
      {
        test: /\.(jpg|png|gif|ico)$/,
        use: {
          loader: "file-loader",
          options: { name: "[path][name].[hash].[ext]" }
        }
      }
    ]
  },
  resolve: { extensions: ["*", ".js", ".jsx"] },
  output: {
    path: __dirname + "/dist",
    publicPath: "/",
    filename: "[name].[hash].js"
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({ hash: false, template: "src/index.html" }),
    new DashboardPlugin(),
    new CopyWebpackPlugin([
      {
        from: "src/components/Assets/BookingBar.js",
        to: "assets/BookingBar.js"
      }
    ]),
    new BundleAnalyzerPlugin()
  ],
  devServer: {
    contentBase: "./dist",
    hot: true,
    historyApiFallback: true,
    port: 4000
  }
};

Какое поведение ожидается?

Должен быть способ исключить файлы .json из основного комплекта. Я пробовал File-Loader, json-loader и const someJson = require (./ someJson)

Другая соответствующая информация: версия веб-пакета: 4.16.1 Версия Node.js: 10.12.0

Операционная система: Mac OS 10.14 Mojave

ОТВЕТЬ НИЖЕ (КАК МЕНЯ, КАК Я РЕШАЛ ЭТО). Я не мог инициализировать лотерею без каких-либо данных.

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

В итоге я взял ответ выше, но не смог инициализировать лотерею без каких-либо данных JSON. Я закончил тем, что сделал это:

import React, { PureComponent } from "react"
import Lottie from 'react-lottie'

export default class AnimationAutomatedCommunication extends PureComponent {

  constructor(props) {
    super(props)
    this.state = {
      animation: <div />
    }
  }

  async componentDidMount() {
    const animation = await import(/* webpackChunkName: "AnimationAutomatedCommunication" */ './JsonData/AnimationAutomatedCommunication.json')
     const defaultOptions = {
       loop: true,
       autoplay: true,
       animationData: animation.default
     }
    this.setState({
      animation: <div className={this.props.className}>
        <Lottie key="lottie-win-jobs" options={defaultOptions}
                isStopped={this.props.isStopped} />
      </div>
    })
  }

  render() {
    return (
      <React.Fragment>
        {this.state.animation}
      </React.Fragment>
    )
  }
}
0 голосов
/ 02 ноября 2018

Ожидаемое поведение заключается в том, что JSON будет упакован, потому что он, по-видимому, необходим синхронно во время выполнения. Данные JSON отличаются от файлов изображений, которые загружаются браузером асинхронно, так как они отображаются на странице с помощью src атрибутов и т. Д.

Как уже упоминалось в комментариях, вы должны использовать разбиение кода. Последняя версия Webpack поддерживает динамический импорт , если вы устанавливаете и используете плагин @babel/plugin-syntax-dynamic-import.

npm install --save-dev @babel/plugin-syntax-dynamic-import

Затем в babel.config.js:

module.exports = {
  ...
  plugins: [
    "@babel/plugin-syntax-dynamic-import"
  ]
  ...
};

Пример

Допустим, у вас есть компонент React, которому могут потребоваться некоторые данные JSON, но не нужно загружать его синхронно как часть пакета. Ваша разделенная версия с кодом non может выглядеть примерно так:

import React from 'react';
import myJSON from './myJSON.json';

export default class MyComponent extends React.Component {
  render() {
    return <div>{JSON.stringify(myJSON, null, 2)}</div>
  }
}

Вместо этого вы можете использовать динамический импорт - в основном импорт во время выполнения, который возвращает Promise, который вы можете использовать для асинхронной загрузки некоторых данных отдельно от вашего пакета:

import React from 'react';
import myJSON from './myJSON.json';

export default class MyComponent extends React.Component {
  state = {data: {}};
  componentDidMount() {
    import(/* webpackChunkName: 'myJSON' */ './myJSON.json')
      .then((data) => {
        this.setState({data});
      });
  }
  render() {
    return <div>{JSON.stringify(this.state.data, null, 2)}</div>
  }
}

В качестве альтернативы, вы можете использовать новый React lazy и Suspense API (v16.6.0 и выше) для , чтобы динамически импортировать компоненты React , которые разделяются на части отдельно от комплекта. Это может быть предпочтительным, если вы хотите объединить компонент и соответствующие ему данные JSON вместе, но отдельно от основного пакета:

// MyComponent.jsx
import React from 'react';
import myJSON from './myJSON.json';

export default class MyComponent extends React.Component {
  render() {
    return <div>{JSON.stringify(myJSON, null, 2)}</div>
  }
}

// SomeParent.jsx
import React, {lazy, Suspense} from 'react';
const MyComponent = lazy(() => import(/* webpackChunkName: 'MyComponent' */ './MyComponent'));

export default class SomeParent extends React.Component {
  render() {
    return <div>
      <Suspense fallback={<div>Loading...<div>} >
        <MyComponent />
      </Suspense>
    </div>;
  }
}

В приведенном выше примере <MyComponent /> и соответствующий ему код, включая данные JSON, будут загружаться только тогда, когда компонент фактически отображается во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...