Class non è un modulo angolare per libreria esterna

Nov 20 2020

Ho creato una semplice Angularapp e aggiunto una libreria personalizzata (stesso progetto):

ng new my-library ng generate library my-library-lib

Quindi per testare questa semplice libreria in un progetto diverso , ho creato la lib:ng build my-library-lib

Ho collegato la lib nella cartella dist e l'ho collegata a un progetto diverso e MyLibraryLibModuleho importato il file nel mioSharedModule

{ MyLibraryLibModule } from 'my-library-lib

imports: [..., MyLibraryLibModule] -> genera un errore: class is not an Angular Module

Questo è un semplice progetto che ho fatto per rifare tutto da zero, non ho modificato nulla nei tsconfigfile ecc. Ho cercato online ma non sono riuscito a trovare alcuna soluzione.

Per testarlo: Repo libreria: https://github.com/GCour/ui-library

Repo di progetto semplice: https://github.com/GCour/ui-test

tsconfig.lib.json:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "../../out-tsc/lib",
    "target": "es2015",
    "declaration": true,
    "declarationMap": true,
    "inlineSources": true,
    "types": [],
    "lib": [
      "dom",
      "es2018"
    ]
  },
  "angularCompilerOptions": {
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "enableResourceInlining": true
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}

tsconfing.lib.prod.json

{
  "extends": "./tsconfig.lib.json",
  "compilerOptions": {
    "declarationMap": false
  },
  "angularCompilerOptions": {
    "enableIvy": false
  }
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ],
    "paths": {
      "my-library-lib": [
        "dist/my-library-lib/my-library-lib",
        "dist/my-library-lib"
      ]
    }
  }
}

Risposte

2 Eliseo Nov 23 2020 at 12:06

Se stai chiedendo informazioni sull'uso nello sviluppatore di una libreria locale , dovresti creare la tua libreria in produzione

ng build my-lib --prod

quindi usa npm linkper creare localmente la tua libreria

cd dist
cd my-lib
npm link

Se tutto va bene, puoi importare in un altro progetto del tuo computer, puoi controllare se la lib è stata aggiunta al tuo npm locale in

C:\Users\[your-user]\AppData\Roaming\npm\node_modules\my-lib

Ora l'unica cosa che devi usare in un altro progetto del tuo computer usando npm link my-library

cd c:\my-another-app\src
npm link my-library

E usa come al solito, nella tua app.module

   import {myLibModule} from 'my-lib'
   //or import {MyLibService} from 'my-lib/public-api' 

   ...
   imports: [myLibModule}
Ronnie Nov 22 2020 at 19:15

È possibile utilizzare questo repository GitHub come riferimento che dimostra l'installazione e l'integrazione delle librerie personalizzate utilizzando npm link.

Il comando di compilazione della CLI angolare utilizza un generatore diverso e richiama uno strumento di compilazione diverso per le librerie rispetto a quanto fa per le applicazioni.


  • Angular CLI ha un meccanismo diverso per la creazione di librerie, basato su a ng-packagrdifferenza della creazione di applicazioni, che utilizza @angular-devkit/build-angulare si basa su webpack.

  • Il sistema di compilazione per le librerie viene aggiunto alle dipendenze solo quando aggiungi una libreria utilizzando ng generate library my-lib. Se hai configurato manualmente l'infrastruttura, potresti volerlo verificare verificando i tuoi file di configurazione.

Fai attenzione con le mappature del percorso TypeScript ..


  • Poiché c'è una differenza nel meccanismo di compilazione, il sorgente TypeScript viene convertito in un codice JavaScript completamente diverso nella libreria compilata rispetto a quanto sarebbe in un'applicazione compilata.

  • Per questo motivo, un'app che dipende da una libreria dovrebbe utilizzare solo i mapping di percorso TypeScript che puntano alla libreria creata. I mapping dei percorsi TypeScript non devono puntare ai file .ts di origine della libreria.

Come affermato nei documenti ufficiali -

.. Quando si crea la propria libreria, deve trovare la mappatura nei percorsi tsconfig.

NOTA: la generazione di una libreria con Angular CLI aggiunge automaticamente il suo percorso al tsconfigfile. La CLI Angular utilizza i tsconfigpercorsi per indicare al sistema di compilazione dove trovare la libreria.

La tua applicazione utilizza il codice di una vecchia build di libreria!


  • Ogni volta che un file all'interno del codice sorgente viene modificato, viene eseguita una compilazione parziale che emette le nuove modifiche dal codice sorgente.

  • Se ritieni che le modifiche al codice della libreria non si riflettano nella tua app, è probabile che la tua app utilizzi una vecchia build della libreria.

  • Puoi ricostruire la tua libreria ogni volta che apporti modifiche, ma questo passaggio aggiuntivo richiede tempo. Possiamo utilizzare la funzione di build incrementale angolare incorporata. Le compilazioni incrementali possono essere eseguite come processo in background nel tuo ambiente di sviluppo.

  • Aggiungi il --watchflag al comando build:$ ng build my-lib --watch

Hai bisogno di condividere il codice della tua libreria al di fuori dell'ambito dell'applicazione?


  • Pubblica la tua libreria su npm per utenti globali.
  • Crea un collegamento locale per la condivisione all'interno di una rete privata.

poiché l'operazione è stata modificata e sta cercando di creare un collegamento locale, quanto segue spiega solo il secondo bit. Per pubblicare la tua libreria su npm-registry, puoi fare riferimento ai documenti ufficiali angular sulla pubblicazione di librerie sul registro npm . Se sei nuovo nel registro npm e questa è la prima volta che pubblichi una libreria, potresti voler controllare i vari motivi da coprire quando pubblichi le tue librerie sul registro npm


Mentre si lavora con npm link...

  • Dopo aver creato la libreria, per verificare se è stata eseguita correttamente, vai alla cartella dist / dell'area di lavoro della tua libreria e verifica il package.jsonfile. Il package.json, dovrebbe avere un attributo main. Assicurati che sia collegato a un'estensione di file .js e non a .ts

  • Ora puoi usarlo npm linkall'interno dell'area di lavoro della tua libreria. Crea un puntatore di riferimento - un collegamento simbolico - all'interno dell'ambiente del nodo locale diretto verso la tua libreria.

  • Una volta creato il riferimento locale, vai nell'area di lavoro del tuo progetto e usa npm link <library-name>. Assicurati che sia il nome della libreria e non il nome dell'area di lavoro della libreria .

  • Nell'area di lavoro del progetto, all'interno node_modulesdi dovresti essere in grado di vedere la tua libreria con un " @ " aggiunto. Ora puoi facilmente importare componenti e servizi rilevanti dalla tua libreria nei tuoi progetti app.module.ts.. o caricarli lentamente se preferisci questo approccio.

Allo stesso modo..

import { FooModule } from 'foo-library';
...