web-dev-qa-db-fra.com

Angular Police Awesome dans une bibliothèque de composants - FontAwesome: icône introuvable avec iconName = times et prefix = fas

J'ai une bibliothèque de composants Angular 7 qui utilise les icônes FontAwesome.

Tout d’abord, sortie de 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

Et des informations pertinentes dans 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",

Voici ma définition de module:

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>
            ]
        };
    }
}

Voici public_api.ts:

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

Je peux construire ce module avec ng build mylib --prod parfaitement. Cependant, lorsque j'essaie de l'utiliser dans une application, chaque fois que l'indicateur --prod est utilisé pour créer ou servir, j'obtiens les erreurs suivantes:

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

Voici le fichier app.module.ts pour l'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 utilise faCalendarIcon et apporte également des composants de LibModule qui utilisent à leur tour les icônes décrites dans la définition du module lib.

L’icône du calendrier s’affiche parfaitement lorsque vous utilisez ng serve --prod ou ng build --prod, puis que vous utilisez l’application sans passer par le serveur de développement angulaire cuit. Cependant, chaque icône utilisée par les composants de la bibliothèque eux-mêmes n'apparaît pas et je vois l'erreur du titre dans la console pour chacun d'entre eux.

Veuillez noter que cela ne se produit pas lorsque j'utilise ng serve sans le drapeau prod, cela peut donc avoir un rapport avec la secousse des arbres?

Comment utiliser FontAwesomeModule dans une bibliothèque et m'assurer que les utilisateurs de la bibliothèque peuvent également voir les icônes? Je préférerais ne pas obliger tous les consommateurs à importer toutes les icônes utilisées par la bibliothèque.

Notez que j'utilise des importations profondes avec mes icônes FontAwesome. J'ai également essayé d'effectuer des importations "superficielles" en tant que telles:

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

J'ai également essayé pour mon module lib d'exporter FontAwesomeModule et de ne pas l'exporter. J'ai essayé d'exporter chaque icône, mais ce n'est pas possible, semble-t-il.

4
Isabelle Plante

OK, nous l'avons compris en interne.

Dans la bibliothèque, les instructions library.add(...) qui flottaient simplement dans le fichier de définition de module de bibliothèque doivent être déplacées vers le constructeur de module. Cela résout le problème.

1
Isabelle Plante

Il y a une autre option.

  1. Créer un nouveau projet ng new ng-fontawesome
  2. Créer une nouvelle bibliothèque dans le projet ng generate library ng-fa
  3. Installez les paquets font-awesome npm install --save @fortawesome/angular-fontawesome @fortawesome/fontawesome-svg-core @fortawesome/free-regular-svg-icons
  4. Mettez à jour projects/ng-fa/src/lib/ng-fa.module.ts pour importer/exporter le module fontawesome

    import { NgModule } from '@angular/core';
    import { NgFaComponent } from './ng-fa.component';
    import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
    
    @NgModule({
      declarations: [NgFaComponent],
      imports: [FontAwesomeModule],
      exports: [NgFaComponent, FontAwesomeModule]
    })
    export class NgFaModule { }
    
  5. Mettez à jour projects/ng-fa/src/lib/ng-fa.component.ts pour utiliser une icône fontawesome

    import { Component } from '@angular/core';
    // import { IconDefinition } from '@fortawesome/fontawesome-common-types';
    import { faAddressBook } from '@fortawesome/free-regular-svg-icons';
    @Component({
      selector: 'lib-ng-fa',
      template: `
        <fa-icon [icon]="icon"></fa-icon>
      `,
      styles: []
    })
    export class NgFaComponent {
      // icon: IconDefinition = faAddressBook;
      icon = faAddressBook;
    }
    
  6. Mettez à jour src/app/app.module.ts pour importer votre module de bibliothèque par nom (chemin non relatif)

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    import { NgFaModule } from 'ng-fa';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule, NgFaModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
  7. Ajoutez des scripts npm pour que la bibliothèque soit créée avant l'application. Dans la balise scripts du fichier package.json principal que j'ai ajouté aux entrées.

    • "build:ng-fa": "ng build ng-fa"
    • "prestart": "npm run build:ng-fa"

J'ai testé cela avec la commande de démarrage mais vous auriez besoin de faire la même chose pour votre commande de construction.

J'ai ensuite exécuté npm run start (dev) et npm run start -- --prod pour tester les deux versions et elles fonctionnent bien. Cela réduit considérablement le besoin de toutes les importations comme vous le faites ci-dessus. Ici, vous devez uniquement importer les icônes dans les composants qui en ont réellement besoin (pas dans le module également).

J'ai créé un GitHub repo avec cet exemple également.

0
peinearydevelopment