rob_was_taken
rob_was_taken

Reputation: 413

react-fontawesome importing all icons

I'm trying to import just the fontawesome icons I need as the full library is 3mb. I've swapped to the fontawesome-react component to enable this but I'm not having much luck.

Here's my test case:

Package includes:

"@fortawesome/fontawesome-svg-core": "^1.2.4",
"@fortawesome/pro-regular-svg-icons": "^5.3.1",
"@fortawesome/react-fontawesome": "^0.1.3",

Component:

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faThumbsUp } from '@fortawesome/pro-regular-svg-icons';

// In Render:
<FontAwesomeIcon
    icon={ faThumbsUp }
/>

Results in an include size of 1MB Is this expected behaviour?

It appears to be following the explicit import methodology - https://github.com/FortAwesome/react-fontawesome#user-content-explicit-import

Visualizer Result

Upvotes: 11

Views: 10186

Answers (5)

Chizaram Igolo
Chizaram Igolo

Reputation: 1143

The TypeScript version of @Wetteren Rémi's Answer

For the TypeScript version of the selected answer, you'll need to:

  1. Type the array argument of the library.add() method as a union of the IconDefinition and IconPack types.
  2. Type the import (Icons) as an interface where each key's value has the resulting union type from (1) and IconPrefix.

import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as Icons from '@fortawesome/free-solid-svg-icons'; 

// Types
import { 
  IconDefinition, 
  IconPrefix, 
  IconPack 
} from "@fortawesome/free-solid-svg-icons";
 
// Type that `library.add()` expects.
type IconDefinitionOrPack = IconDefinition | IconPack;

interface ImportedIcons {
    [key: string]: IconPrefix | IconDefinitionOrPack;
} 

// Type `Icons` as a interface containing keys whose values are 
// union of the resulting union type from above and `IconPrefix`.
const iconList = Object
  .keys(Icons)
  .filter(key => key !== "fas" && key !== "prefix" )
  .map(icon => (Icons as ImportedIcons)[icon])

library.add(...(iconList as IconDefinitionOrPack[]))

Then you can use it in your components like this:

<FontAwesomeIcon icon="check" />

Upvotes: 5

Christian
Christian

Reputation: 158

If you think tree shaking is not working, You can find solutions in here. But most of the times this is solved by using deep imports:

import { faCoffee } from '@fortawesome/free-solid-svg-icons/faCoffee' // <-- note the extra faCoffee there

But if you want to import all the icons at once, according to Importing Icons you can import all the icons in this way:

import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'

// Add all icons to the library so you can use it in your page
library.add(fas, far, fab)

And if the icon have many variations in a library, you can use it like this:

<FontAwesomeIcon icon={['fas', 'smile']} />
<FontAwesomeIcon icon={['far', 'smile']} />

Since all the icons are in the library now, there's no need to import them one by one.

Upvotes: 3

Wetteren R&#233;mi
Wetteren R&#233;mi

Reputation: 628

If you would like to use whatever icon you want with the easiest configuration through the new Fontawesome React library, here how you could do:

import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as Icons from '@fortawesome/free-solid-svg-icons';

const iconList = Object
  .keys(Icons)
  .filter(key => key !== "fas" && key !== "prefix" )
  .map(icon => Icons[icon])

library.add(...iconList)

(Tips: the (...iconList) is used here to add each object we have as an array as function parameters)

Then add into your code wherever you want

<FontAwesomeIcon icon="check" />

Now you can use all icons without having to import them all 🤙

Upvotes: 21

rob_was_taken
rob_was_taken

Reputation: 413

Discussed this with the react-fa team and they advised that icons need to be explicitly imported with full paths:

import { faThumbsUp } from '@fortawesome/pro-regular-svg-icons/faThumbsUp';

This means that the remaining items will be removed during the 'tree-shaking' process by Webpack. There's no mention of this so I made a suggestion that this should be mentioned in the explicit import section of the docs.

Anyhoo - all working now so thanks to those guys over at FA.

Upvotes: 5

ramusus
ramusus

Reputation: 8315

In our project we use this scss technique ([email protected]):

@import '~font-awesome/scss/font-awesome';

@mixin fa-icon($type) {
  @extend .fa;
  @extend .fa-#{$type};
}

i {
  @include fa-icon('star');
  margin-right: 0.2rem;
}

As result we have only icons we need in our css bundles.

UPDATE: Using react components with babel-plugin-react-css-modules we can reuse and apply any icon styles from font-awesome lib directly to our own classes:

.button {
  i {
    @include fa-icon('star');
  }
}

Upvotes: 3

Related Questions