Условно импортировать активы в приложение create-реагировать - PullRequest
11 голосов
/ 06 марта 2019

Можно ли условно импортировать активы при создании приложения React с помощью create-реагировать-приложение?Я знаю о синтаксисе require - пример:

import React from "react";


const path = process.env.REACT_APP_TYPE === "app_1" ? "app_1" : "app_2";

const imagePath = require(`./assets/${path}/main.png`);

export default function Test() {
  return (
      <img src={imagePath} alt="" />
  );
}

Это, однако, объединяет все мои активы, несмотря ни на что.

Он загрузит нужный образ, но все равно объединит все файлы вместе в окончательной сборке.

Когда я просматриваю инструменты разработчика для окончательной сборки, я вижу все активы там, хотя я только хотел загрузить активы для app_1.

Я вынужден коснутьсяКонфигурация веб-пакета, если так, что я должен изменить?или есть другой способ?

Ответы [ 3 ]

7 голосов
/ 08 марта 2019

В те времена, когда React не существовало, мы не помещали ресурсы в наши файлы JS. Мы позволяем CSS решать, какие активы загружать для каких селекторов. Затем вы можете просто включить или отключить соответствующий класс для соответствующего элемента ( или даже всей страницы ) и изменить его, изменив цвет, фон или даже форму. Чистая магия!

Ах. Какие времена это были!

Все вышеизложенное верно, и я не понимаю, почему кто-то делает или рекомендует делать это по-другому. Однако, если вы все еще хотите это сделать ( по любой причине ) - вы можете! Последняя версия create-react-app поставляется с готовой поддержкой отложенной загрузки произвольных компонентов через динамический импорт и разбиение кода . Все, что вам нужно сделать, это использовать заключенную в скобки версию оператора import() вместо обычной. import() принимает строку запроса как обычно и возвращает Обещание. Вот и все. Исходный код динамически запрашиваемого компонента не будет упакован, а вместо этого сохранен в отдельных блоках для загрузки по требованию.

До:

import OtherComponent from './OtherComponent';

function MyComponent() {   
  return (
    <div>
      <OtherComponent />
    </div>   
  ); 
}

После того, как:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}

Обратите внимание , как function MyComponent часть идентична.

Для тех, кому интересно, связано ли это с CRA или React, это не так. Это общая концепция, что может использоваться в ванильном JavaScript .

6 голосов
/ 08 марта 2019

Вам потребуется для использования веб-пакета (или другого упаковщика). Код не запускается, когда он упакован, поэтому у компилятора нет возможности узнать, какой ветви логики следовать (app_1 или app_2),Поэтому вам нужно войти в логику компоновщика, чтобы достичь своей цели.

Однако, это не так страшно, как кажется, так как в webpack есть встроенная возможность сделать это (сторонних разработчиков не требуется ...)

Я хотел бы изучить использование webpack.providePlugin

(https://webpack.js.org/plugins/provide-plugin)

или его родственника DefinePlugin

(https://webpack.js.org/plugins/define-plugin)

(Боюсь, что эти примеры не в моей голове, поэтому очень маловероятно, что они будут работать при первом проходе.)

Примеры:

Для обоих потребуется модуль поставщика...

// in path/provider.js

module.exports = {
  live: '/path/to/live/image',
  dev: '/path/to/dev/image'
}

Пример предоставления плагина

// in webpack

new webpack.ProvidePlugin({
    imagePath: [
      'path/provider',         // the file defined above
      process.env.ENVIRONMENT  // either 'dev' or 'live'
    ]
  }),
// in code

export default function Test() {
  return (
      <img src={imagePath} alt="" />
  );
}

Пример определения плагина:

// in webpack

new webpack.DefinePlugin({
  'process.env.ENVIRONMENT': JSON.stringify(process.env.ENVIRONMENT)
});
// in code

var providers = require('path/provider'); // same path provider as above

export default function Test() {
  return (
      <img src={providers[process.env.ENVIRONMENT]} alt="" />
  );
}

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

3 голосов
/ 09 марта 2019

Вы не можете сделать это с настройками CRA по умолчанию .

Потому что, если ваш динамический требует или динамический импорт путь не static , веб-пакет не сможет определить, какие ресурсы следует включить в папку окончательной сборки, поэтому он извлечет все из вашей папки ./src и поместит их все в вашу папку build.

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