angularfont-awesome-5

Angular Font Awesome in a component library - FontAwesome: Could not find icon with iconName=times and prefix=fas


I have an Angular 7 component library that uses FontAwesome icons.

First of all, output of ng version:

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.10.7
@angular-devkit/build-angular      0.10.7
@angular-devkit/build-ng-packagr   0.10.7
@angular-devkit/build-optimizer    0.10.7
@angular-devkit/build-webpack      0.10.7
@angular-devkit/core               7.0.7
@angular-devkit/schematics         7.0.7
@angular/cdk                       7.1.1
@angular/cli                       7.0.7
@angular/compiler-cli              7.0.4
@angular/language-service          7.0.4
@angular/material                  7.1.1
@ngtools/json-schema               1.1.0
@ngtools/webpack                   7.0.7
@schematics/angular                7.0.7
@schematics/update                 0.10.7
ng-packagr                         4.4.5
rxjs                               6.3.3
typescript                         3.1.3
webpack                            4.19.1

And relevant tidbits in package.json:

"@fortawesome/angular-fontawesome": "^0.3.0",
"@fortawesome/fontawesome-svg-core": "^1.2.8",
"@fortawesome/free-regular-svg-icons": "^5.5.0",
"@fortawesome/free-solid-svg-icons": "^5.5.0",

Here's my module definition:

import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { library } from '@fortawesome/fontawesome-svg-core';

import { faAngleDown } from '@fortawesome/free-solid-svg-icons/faAngleDown';
import { faBars } from '@fortawesome/free-solid-svg-icons/faBars';
import { faCalendarAlt } from '@fortawesome/free-solid-svg-icons/faCalendarAlt';
import { faCaretLeft } from '@fortawesome/free-solid-svg-icons/faCaretLeft';
import { faChevronDown } from '@fortawesome/free-solid-svg-icons/faChevronDown';
import { faSortUp } from '@fortawesome/free-solid-svg-icons/faSortUp';
import { faSortDown } from '@fortawesome/free-solid-svg-icons/faSortDown';
import { faChevronUp } from '@fortawesome/free-solid-svg-icons/faChevronUp';
import { faChevronLeft } from '@fortawesome/free-solid-svg-icons/faChevronLeft';
import { faTimes } from '@fortawesome/free-solid-svg-icons/faTimes';
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';
import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons/faSignOutAlt';
import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons/faQuestionCircle';
import { faGlobeAmericas } from '@fortawesome/free-solid-svg-icons/faGlobeAmericas';

<app imports>

library.add(
    faAngleDown, faBars, faCalendarAlt, faCaretLeft, faChevronDown,
    faChevronLeft, faChevronUp, faGlobeAmericas, faQuestionCircle, 
    faSignOutAlt, faSortDown, faSortUp, faTimes, faUser
);

@NgModule({
    declarations: [
        <app components>
    ],
    exports: [
        <app components>
    ],
    imports: [
        FontAwesomeModule,
        <other app imports>
    ]
})
export class LibModule {
    public static forRoot(): ModuleWithProviders {
        return {
            ngModule: LibModule,
            providers: [
                <some providers>
            ]
        };
    }
}

Here's public_api.ts:

export * from './lib/lib.module';
<component exports>

I can build this module with ng build mylib --prod just fine. However, when I try to use it in an application, whenever the --prod flag is used to build or serve, I get the following errors:

FontAwesome: Could not find icon with iconName=times and prefix=fas

Here's the app.module.ts file for the application:

import { faCalendarAlt } from '@fortawesome/free-solid-svg-icons';
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { LibModule } from 'libmodule';

<app imports>

library.add(faCalendarAlt);

@NgModule({
    bootstrap: [ AppComponent ],
    declarations: [
        AppComponent,
    ],
    imports: [
        FontAwesomeModule,
        LibModule.forRoot(),
    ]
})
export class AppModule {
}

app.component.ts is using the faCalendarIcon, and also bringing in components from LibModule which in turn are using the icons described in the lib module definition.

The calendar icon displays just fine when using ng serve --prod or ng build --prod and then serving the application not through the baked angular dev server. However, every icon used by the library components themselves don't show up, and I see the error from the title in the console for every one of them.

Please note that this doesn't happen when I use ng serve without the prod flag, so it may have something to do with tree-shaking?

How can I use FontAwesomeModule within a library and make sure that the consumers of the library can see the icons as well? I'd rather not have to make all consumers import all icons used by the library.

Note that I'm using deep imports with my FontAwesome icons, I've also tried to do "shallow" imports as such:

import {
  faAngleDown,
  faBars,
  faCalendarAlt,
  faCaretLeft,
  faChevronDown,
  faChevronLeft,
  faChevronUp,
  faGlobeAmericas,
  faQuestionCircle,
  faSignOutAlt,
  faSortDown,
  faSortUp,
  faTimes,
  faUser
} from '@fortawesome/free-solid-svg-icons';

I've also tried for my lib module to export FontAwesomeModule, and not to export it. I've tried exporting each icon, but that's not possible it seems.


Solution

  • OK, we figured it out internally.

    In the library, the library.add(...) statements that were just floating in the library module definition file need to move to the module constructor. This solves the issue.