最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Import React Material UI Icons dynamically - Stack Overflow

programmeradmin2浏览0评论

The main idea is to only import react material UI icons when it is needed or rather when dynamically where we wouldn't know the icon name at pile time. (Let's gurentee that we would have valid icon names).

My approach was to use a require statment with dynamic path:

const IconComponent = require(`@material-ui/icons/${icon}`).default;

This works fine but some warnings are showing up.

./node_modules/@material-ui/icons/utils/createSvgIcon.d.ts 3:8 Module parse failed: Unexpected token (3:8) You may need an appropriate loader to handle this file type. | import SvgIcon from '@material-ui/core/SvgIcon'; | declare function createSvgIcon(path: React.ReactNode, displayName: string): typeof SvgIcon; | | export default createSvgIcon;

./node_modules/@material-ui/icons/index.d.ts 4:5 Module parse failed: Unexpected token (4:5) You may need an appropriate loader to handle this file type. | import SvgIcon from '@material-ui/core/SvgIcon'; |

type SvgIconComponent = typeof SvgIcon; | | export const AccessAlarm: SvgIconComponent;

My question is: How could we avoid these warnings and do the dynamic import in the appropriate way ?

The main idea is to only import react material UI icons when it is needed or rather when dynamically where we wouldn't know the icon name at pile time. (Let's gurentee that we would have valid icon names).

My approach was to use a require statment with dynamic path:

const IconComponent = require(`@material-ui/icons/${icon}`).default;

This works fine but some warnings are showing up.

./node_modules/@material-ui/icons/utils/createSvgIcon.d.ts 3:8 Module parse failed: Unexpected token (3:8) You may need an appropriate loader to handle this file type. | import SvgIcon from '@material-ui/core/SvgIcon'; | declare function createSvgIcon(path: React.ReactNode, displayName: string): typeof SvgIcon; | | export default createSvgIcon;

./node_modules/@material-ui/icons/index.d.ts 4:5 Module parse failed: Unexpected token (4:5) You may need an appropriate loader to handle this file type. | import SvgIcon from '@material-ui/core/SvgIcon'; |

type SvgIconComponent = typeof SvgIcon; | | export const AccessAlarm: SvgIconComponent;

My question is: How could we avoid these warnings and do the dynamic import in the appropriate way ?

Share Improve this question asked Dec 11, 2020 at 10:14 SoS 777SoS 777 411 silver badge4 bronze badges 2
  • please provide a snippet with a reproducible situation so we can use it as a starting point. – Renan Souza Commented Dec 12, 2020 at 0:20
  • This appears to be a duplicate of another question, where I've posted an answer that may be helpful: stackoverflow./a/77332935 – James Porter Commented Oct 30, 2023 at 10:13
Add a ment  | 

2 Answers 2

Reset to default 3

You can create a hook for this. like the following.

//1) $ npm i string-similarity
import * as icons from '@material-ui/icons'
import stringSimilarity from 'string-similarity'

function useIcons(word) {
  const iconsNames = Object.keys(icons)

  var matches = stringSimilarity.findBestMatch(word, iconsNames)
  const bestMathch = matches.bestMatch.target
  const Icon = icons[bestMathch]
  return Icon
}
export default useIcons

import Icon from './myCustomeHooks/useIcons'
// other file like
const Icon =  useIcons('tablechart')  // not the name should start with capital letter in case you use reactjs


// now you can use the icon as you like
<Icon/>



please note: import * as icons from '@material-ui/icons' is the same as const * as icons = require('@material-ui/icons').default;


option 2

import React from 'react';
import { loadCSS } from 'fg-loadcss';
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import { green } from '@material-ui/core/colors';
import Icon from '@material-ui/core/Icon';

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      '& > .fa': {
        margin: theme.spacing(2),
      },
    },
  }),
);

export default function FontAwesome() {
  const classes = useStyles();

  React.useEffect(() => {
    const node = loadCSS(
      'https://use.fontawesome./releases/v5.12.0/css/all.css',
      document.querySelector('#font-awesome-css'),
    );

    return () => {
      node.parentNode!.removeChild(node);
    };
  }, []);

  return (
    <div className={classes.root}>
      <Icon className="fa fa-plus-circle" />
      <Icon className="fa fa-plus-circle" color="primary" />
      <Icon className="fa fa-plus-circle" color="secondary" />
      <Icon className="fa fa-plus-circle" style={{ color: green[500] }} />
      <Icon className="fa fa-plus-circle" fontSize="small" />
      <Icon className="fa fa-plus-circle" style={{ fontSize: 30 }} />
    </div>
  );
}

first is

(async () => {
  if (somethingIsTrue) {
    const { default: myDefault, foo, bar } = await 
import('/modules/my-module.js');
  }
})();

second method is

let module = await import('/modules/my-module.js');

nice working example you can tweak is

const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a")) {
 link.addEventListener("click", e => {
 e.preventDefault();

 import('/modules/my-module.js')
   .then(module => {
     module.loadPageInto(main);
   })
    .catch(err => {
     main.textContent = err.message;
    });
 }
发布评论

评论列表(0)

  1. 暂无评论