From fb83a23498744f7f2376b8748eea7f61189b7c5d Mon Sep 17 00:00:00 2001 From: saurabhraghuvanshii Date: Mon, 14 Sep 2026 03:17:00 +0530 Subject: [PATCH] perf: import MUI icons by path instead of the barrel Seven components imported icons from the `@mui/icons-material` barrel. The rollup build keeps dependencies external, so `dist/index.js` shipped a `require('@mui/icons-material')` for 11 icons, and every consumer's bundler then had to resolve and parse the ~10,800 modules that barrel re-exports. Import each icon by path and add a `no-restricted-imports` lint rule so the barrel cannot come back. The built bundle now has zero barrel requires and 11 deep ones. All 236 tests pass; the 8 remaining lint errors are pre-existing class-field parsing errors, identical on master. Signed-off-by: saurabhraghuvanshii --- eslint.config.js | 13 +++++++++++++ src/components/ExpandButton.js | 3 ++- src/components/Popover.js | 2 +- src/components/TableHeadCell.js | 2 +- src/components/TableSearch.js | 3 ++- src/components/TableToolbar.js | 12 +++++------- src/components/TableToolbarSelect.js | 2 +- src/plug-ins/DebounceSearchRender.js | 3 ++- 8 files changed, 27 insertions(+), 13 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 9b862de..5b0c9d8 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -41,6 +41,19 @@ module.exports = [ 'no-undef': 2, 'no-undef-init': 2, 'no-tabs': 2, + // The @mui/icons-material barrel re-exports ~10,800 modules that every + // consumer's bundler has to parse. Import icons by path instead. + 'no-restricted-imports': [ + 2, + { + paths: [ + { + name: '@mui/icons-material', + message: "Import icons by path, e.g. '@mui/icons-material/Search'.", + }, + ], + }, + ], 'react/self-closing-comp': 2, 'react/no-typos': 2, 'react/jsx-no-duplicate-props': 'warn', diff --git a/src/components/ExpandButton.js b/src/components/ExpandButton.js index cc58993..63a496c 100644 --- a/src/components/ExpandButton.js +++ b/src/components/ExpandButton.js @@ -1,6 +1,7 @@ import React from 'react'; import { IconButton } from '@mui/material'; -import { KeyboardArrowRight as KeyboardArrowRightIcon, Remove as RemoveIcon } from '@mui/icons-material'; +import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import RemoveIcon from '@mui/icons-material/Remove'; const ExpandButton = ({ areAllRowsExpanded, diff --git a/src/components/Popover.js b/src/components/Popover.js index 1dd2918..76bdcaa 100644 --- a/src/components/Popover.js +++ b/src/components/Popover.js @@ -1,7 +1,7 @@ import React, { useEffect, useRef, useState } from 'react'; import PropTypes from 'prop-types'; import { Popover as MuiPopover, IconButton } from '@mui/material'; -import { Close as CloseIcon } from '@mui/icons-material'; +import CloseIcon from '@mui/icons-material/Close'; const Popover = ({ className, trigger, refExit, hide, content, ...providedProps }) => { const [isOpen, open] = useState(false); diff --git a/src/components/TableHeadCell.js b/src/components/TableHeadCell.js index fd91c08..dcd19b7 100644 --- a/src/components/TableHeadCell.js +++ b/src/components/TableHeadCell.js @@ -1,5 +1,5 @@ import { Button, TableCell, TableSortLabel, Tooltip as MuiTooltip } from '@mui/material'; -import { Help as HelpIcon } from '@mui/icons-material'; +import HelpIcon from '@mui/icons-material/Help'; import clsx from 'clsx'; import PropTypes from 'prop-types'; import React, { useState } from 'react'; diff --git a/src/components/TableSearch.js b/src/components/TableSearch.js index 01227f0..574722b 100644 --- a/src/components/TableSearch.js +++ b/src/components/TableSearch.js @@ -1,6 +1,7 @@ import React from 'react'; import { Grow, TextField, IconButton } from '@mui/material'; -import { Search as SearchIcon, Clear as ClearIcon } from '@mui/icons-material'; +import SearchIcon from '@mui/icons-material/Search'; +import ClearIcon from '@mui/icons-material/Clear'; import { makeStyles } from 'tss-react/mui'; const useStyles = makeStyles({ name: 'MUIDataTableSearch' })((theme) => ({ diff --git a/src/components/TableToolbar.js b/src/components/TableToolbar.js index f9d1f7f..803c857 100644 --- a/src/components/TableToolbar.js +++ b/src/components/TableToolbar.js @@ -1,12 +1,10 @@ import React from 'react'; import { Typography, Toolbar, IconButton, Tooltip as MuiTooltip } from '@mui/material'; -import { - Search as SearchIcon, - CloudDownload as DownloadIcon, - Print as PrintIcon, - ViewColumn as ViewColumnIcon, - FilterList as FilterIcon, -} from '@mui/icons-material'; +import SearchIcon from '@mui/icons-material/Search'; +import DownloadIcon from '@mui/icons-material/CloudDownload'; +import PrintIcon from '@mui/icons-material/Print'; +import ViewColumnIcon from '@mui/icons-material/ViewColumn'; +import FilterIcon from '@mui/icons-material/FilterList'; import Popover from './Popover'; import TableFilter from './TableFilter'; import TableViewCol from './TableViewCol'; diff --git a/src/components/TableToolbarSelect.js b/src/components/TableToolbarSelect.js index 6bac377..8733f27 100644 --- a/src/components/TableToolbarSelect.js +++ b/src/components/TableToolbarSelect.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Paper, IconButton, Typography, Tooltip as MuiTooltip } from '@mui/material'; -import { Delete as DeleteIcon } from '@mui/icons-material'; +import DeleteIcon from '@mui/icons-material/Delete'; import { withStyles } from 'tss-react/mui'; const defaultToolbarSelectStyles = (theme) => ({ diff --git a/src/plug-ins/DebounceSearchRender.js b/src/plug-ins/DebounceSearchRender.js index 4817c8f..27557a5 100644 --- a/src/plug-ins/DebounceSearchRender.js +++ b/src/plug-ins/DebounceSearchRender.js @@ -1,6 +1,7 @@ import React from 'react'; import { Grow, TextField, IconButton } from '@mui/material'; -import { Search as SearchIcon, Clear as ClearIcon } from '@mui/icons-material'; +import SearchIcon from '@mui/icons-material/Search'; +import ClearIcon from '@mui/icons-material/Clear'; import { withStyles } from 'tss-react/mui'; function debounce(func, wait, immediate) {