10

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

rob_was_taken
  • 384
  • 4
  • 14

5 Answers5

19

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

Wetteren Rémi
  • 598
  • 6
  • 11
  • this is great, now I can try however many I want out and pare them down when I go to production. So convenient! Thank you. – AveryFreeman Jul 12 '20 at 04:35
  • 2
    This is cool, any idea on how to do it with typescript? I'm getting this error here on Icons[icon] `Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof import` – Arturio Nov 30 '20 at 16:50
  • @Arturio, check out my answer where I show a TypeScript version of this answer. – Chizaram Igolo Jun 16 '22 at 11:49
5

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.

rob_was_taken
  • 384
  • 4
  • 14
3

In our project we use this scss technique (font-awesome@4.7.0):

@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');
  }
}
ramusus
  • 7,789
  • 5
  • 38
  • 45
  • Thanks @ramusus - that wouldn't work for us at the moment sadly as we have a need to build icon names in the application. It might be worth looking at in the future though, thanks! – rob_was_taken Oct 03 '18 at 17:55
  • I don't see this technique in the FA manual, is it documented? – rob_was_taken Oct 03 '18 at 17:59
  • what do you mean by "build icon names in the app" ? I updated the answer with css modules mention – ramusus Oct 03 '18 at 20:49
  • Sorry, badly explained. The icons are added by JS devs that don't have access (or knowledge of) the SASS build tools. We use the icon SVG as part of a central `` component so it makes sense for the Icon library to live there. I'm sure your technique would work perfectly well but would be a significant code change for us at the moment :) - I got a good reply from the dev team so I'll post it here. – rob_was_taken Oct 04 '18 at 21:32
3

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" />
Chizaram Igolo
  • 907
  • 8
  • 18
2

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.

Christian
  • 148
  • 8