Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally import assets in create-react-app

Is it possible to conditionally import assets when creating a React app using create-react-app? I'm aware of the require syntax - example:

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="" />
  );
}

This however bundles all my assets no matter what.

It will load the proper image, but it will still bundle all the files together in the final build.

When I look in the dev tools for the final build, I can see all the assets there even though I only wanted to load the assets for app_1.

Am I forced to touch the webpack config, if so, what should I change? or is there another way?

like image 206
jones Avatar asked Mar 06 '19 11:03

jones


People also ask

How do I import component dynamically into React?

In React, dynamically importing a component is easy—you invoke React. lazy with the standard dynamic import syntax and specify a fallback UI. When the component renders for the first time, React will load that module and swap it in.

How do you lazy load a component in React?

Take any component that you want to lazy load and change it to the following: - import MyComponent from './MyComponent'; + const MyComponent = React. lazy(() => import('./MyComponent')); You can do the same for library components as well.

Do I have to import React in every component?

You no longer need to import React from "react" . Starting from the release 17 of React, JSX is automatically transformed without using React. createElement . However, other exports like hooks must be imported.


1 Answers

In the days when React didn't exist we didn't put assets into our JS files. We let the CSS to decide, what assets to load for what selectors. Then you could simply switch a corresponding class on or off for a corresponding element (or even the whole page) and viola it changes color, background, or even a form. Pure magic!

Ah. What times these were!

All above is true and I do not understand why would anyone do or recommend doing it differently. However if you still want to do it (for any reason) - you can! Latest create-react-app comes with out-of-the-box support for lazy loading of arbitrary components via dynamic importing and code splitting. All you need to do is use parenthesized version of the import() statement instead of the regular one. import() takes in a request string as usual and returns a Promise. That's it. Source code of the dynamicaly requested component won't be bundled in, but instead stored in separate chunks to be loaded on demand.

Before:

import OtherComponent from './OtherComponent';

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

After:

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

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

Notice how function MyComponent part is identical.

For those wondering if it is tied to CRA or React, it's not. It's a generic concept that can be used in vanilla JavaScript.

like image 113
jayarjo Avatar answered Sep 30 '22 11:09

jayarjo