A classe não é um módulo Angular para biblioteca externa

Nov 20 2020

Eu criei um Angularaplicativo simples e adicionei uma biblioteca personalizada (mesmo projeto):

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

Então, para testar essa biblioteca simples em um projeto diferente , construí a biblioteca:ng build my-library-lib

Vinculei a lib na pasta dist e vinculei a um projeto diferente e importei a MyLibraryLibModuleem meuSharedModule

{ MyLibraryLibModule } from 'my-library-lib

imports: [..., MyLibraryLibModule] -> gera erro: class is not an Angular Module

Este é um projeto simples que fiz para refazer tudo do zero, não alterei nada nos tsconfigarquivos etc. Procurei online mas não encontrei nenhuma solução.

Para testá-lo: Repo da biblioteca: https://github.com/GCour/ui-library

Repo de projeto simples: 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"
      ]
    }
  }
}

Respostas

2 Eliseo Nov 23 2020 at 12:06

Se você está perguntando sobre o uso no desenvolvedor de uma biblioteca local, você deve criar sua biblioteca em produção

ng build my-lib --prod

em seguida, use npm linkpara criar localmente sua biblioteca

cd dist
cd my-lib
npm link

Se tudo estiver ok, você pode importar em outro projeto do seu computador, você pode verificar se o lib foi adicionado ao seu npm local em

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

Agora a única coisa que você precisa usar em outro projeto do seu computador usando npm link my-library

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

E use normalmente, em seu app.module

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

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

Você pode usar este repositório GitHub para referência que demonstra a configuração e integração das bibliotecas personalizadas usando npm link.

O comando de construção Angular CLI usa um construtor diferente e invoca uma ferramenta de construção diferente para bibliotecas e aplicações.


  • O Angular CLI tem um mecanismo diferente para construir bibliotecas, baseado em, ng-packagrao contrário de construir aplicativos, que usa @angular-devkit/build-angulare é baseado em webpack.

  • O sistema de construção para bibliotecas só é adicionado às suas dependências quando você adiciona uma biblioteca usando ng generate library my-lib. Se você configurou manualmente a infraestrutura, pode querer ter certeza disso verificando seus arquivos de configuração.

Tenha cuidado com os mapeamentos de caminho do TypeScript.


  • Como há uma diferença no mecanismo de construção, a fonte do TypeScript é convertida em um código JavaScript totalmente diferente na biblioteca construída do que seria em um aplicativo construído.

  • Por esse motivo, um aplicativo que depende de uma biblioteca deve usar apenas mapeamentos de caminho do TypeScript que apontam para a biblioteca construída. Os mapeamentos de caminho do TypeScript não devem apontar para os arquivos .ts de origem da biblioteca.

Conforme declarado nos documentos oficiais -

.. Quando você constrói sua própria biblioteca, ela precisa encontrar o mapeamento em seus caminhos tsconfig.

NOTA: Gerar uma biblioteca com o Angular CLI adiciona automaticamente seu caminho ao tsconfigarquivo. O Angular CLI usa os tsconfigcaminhos para informar ao sistema de construção onde encontrar a biblioteca.

Seu aplicativo está usando código de uma construção de biblioteca antiga!


  • Cada vez que um arquivo no código-fonte é alterado, uma compilação parcial é executada e emite as novas alterações do código-fonte.

  • Se você acredita que suas alterações no código da biblioteca não se refletem em seu aplicativo, provavelmente seu aplicativo está usando uma versão antiga da biblioteca.

  • Você pode reconstruir sua biblioteca sempre que fizer alterações nela, mas essa etapa extra leva tempo. Podemos fazer uso do recurso de construção incremental embutido do Angular. As compilações incrementais podem ser executadas como um processo em segundo plano em seu ambiente de desenvolvimento.

  • Adicione a --watchsinalização ao comando build:$ ng build my-lib --watch

Precisa compartilhar seu código de biblioteca fora do escopo do aplicativo?


  • Publique sua biblioteca no npm para usuários globais.
  • Crie um link local para compartilhar em uma rede privada.

como o op foi editado e está procurando criar um link local, o seguinte explica apenas o segundo bit. Para publicar sua biblioteca no npm-registry, você pode consultar a documentação oficial do angular sobre bibliotecas de publicação no registro npm . Se você é novo no registro npm e esta é a primeira vez que está publicando uma biblioteca, você pode querer verificar os vários motivos a serem cobertos ao publicar suas bibliotecas no registro npm


Enquanto trabalhava com npm link...

  • Depois de construir sua biblioteca, para verificar se ela foi feita corretamente, vá até a pasta dist / da área de trabalho de sua biblioteca e verifique o package.jsonarquivo. O package.json, deve ter um atributo main. Certifique-se de que ele esteja vinculado a uma extensão de arquivo .js e não a .ts

  • Agora você pode usar npm linkdentro do espaço de trabalho de sua biblioteca. Ele cria um ponteiro de referência - um link simbólico - dentro do ambiente de nó local direcionando para sua biblioteca.

  • Depois que a referência local for criada, vá para a área de trabalho do projeto e use npm link <library-name>. Certifique-se de que é o nome da biblioteca e não o nome do espaço de trabalho da biblioteca .

  • Na área de trabalho do projeto, no, node_modulesvocê deve ser capaz de ver sua biblioteca com um ' @ ' anexado a ela. Agora você pode importar facilmente componentes e serviços relevantes de sua biblioteca para seus projetos app.module.ts... ou carregá-los lentamente, se preferir essa abordagem.

Da mesma forma..

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