Angular: Compilação Angular2 AOT - "Não é possível determinar o módulo para a classe (... muitos componentes que não são usados)"

Criado em 20 dez. 2016  ·  183Comentários  ·  Fonte: angular/angular

[ x ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Comportamento atual
Componentes/pipes/diretivas não utilizados no meu espaço de trabalho são detectados pelo compilador, que lança o erro Cannot determine the module for class (...) para cada arquivo. Ele interrompe a compilação e não parece ser configurável. Isso é um problema, pois preciso ter esses arquivos no meu espaço de trabalho, mas não preciso deles no aplicativo resultante (implementações de parceiros que exigem diferentes combinações de componentes compartilhados). Isso é especialmente frustrante no que diz respeito à compilação em um carregador de webpack, que deve fornecer uma lista de arquivos incluídos, independentemente do espaço de trabalho.

Comportamento esperado
Eu esperaria que esses erros fossem avisos e/ou pudessem ser silenciados por uma opção do compilador. Alternativamente, com relação ao webpack, você pode permitir que uma lista de arquivos seja inserida, para que um webpack possa fornecer todos os arquivos na cadeia require, em vez de todos os arquivos na área de trabalho.

Reprodução mínima do problema com instruções
Não é possível demo no plunkr, pois ele usa JIT.

  1. Crie um aplicativo angular básico que inicializa um ngModule com um componente, AppComponent
  2. Coloque este aplicativo em um estado que possa ser compilado AOT (deve ser muito fácil com um hello world)
  3. Adicione um componente à estrutura de diretórios, mas não faça referência a ele em nenhum lugar do seu código.
  4. Tente compilar AOT novamente. Você receberá o aviso Cannot determine the module for class

Qual é a motivação/caso de uso para mudar o comportamento?
Minha empresa tem um aplicativo básico para nós mesmos e nossos parceiros usam versões modificadas desse aplicativo como se fossem deles. Em vez de manter todos os parceiros separadamente, usamos uma biblioteca compartilhada de componentes genéricos comuns, importados conforme necessário. Para nosso aplicativo base, está tudo bem, pois usamos todos os componentes. Para parceiros, não podemos usar AOT, pois alguns dos componentes do pacote npm compartilhado não possuem um módulo declarado.

Por favor, conte-nos sobre o seu ambiente:
Acontece em todos os dispositivos, mas a configuração de teste atual é:
Windows 10
Código VS
Cmder (terminal bash)

  • Versão angular:
    v2.1.0 (embora também tenhamos testado em 2.3.1

  • Navegador: Todos - este é um problema do compilador, não específico do navegador

  • Idioma: Datilografado

  • Nó (para problemas de AoT): nó v6.3.0
P5 compiler NgModule ve low error messages triage #1 confusing

Comentários muito úteis

@DzmitryShylovich Faz sentido que os componentes que você está USANDO precisem fazer parte de um módulo. Mas no que diz respeito ao compilador, esses arquivos não devem importar. Eles são arquivos .ts não usados ​​e não referenciados que contêm componentes.

Todos 183 comentários

Não é possível determinar o módulo para a classe

O componente deve fazer parte de um módulo. É pretendido.
Eu diria que é um pedido de recurso.

@DzmitryShylovich Faz sentido que os componentes que você está USANDO precisem fazer parte de um módulo. Mas no que diz respeito ao compilador, esses arquivos não devem importar. Eles são arquivos .ts não usados ​​e não referenciados que contêm componentes.

@swimmadude66 você pode excluir arquivos não utilizados no tsconfig

@DzmitryShylovich você pode, mas arquivos de barril complicam isso. Se uma classe for reexportada em um arquivo de barril, eu também tenho que ignorar o arquivo de barril, o que pode causar problemas com as classes que eu preciso desse barril.

Parece estranho que o compilador tente compilar mais do que o necessário. Deixando de lado o tremor de árvore, eu esperaria que o compilador quisesse lidar apenas com arquivos fornecidos a ele ou explicitamente vinculados a arquivos fornecidos.

Parece estranho que o compilador tente compilar mais do que o necessário.

é assim que os compiladores funcionam...

O fato de a compilação JIT funcionar deve ser uma boa evidência de que o compilador NÃO PRECISA desses arquivos. Ele está lançando um erro em vez de um aviso em arquivos que podem ser excluídos sem nenhum dano.

você pode falar comigo sobre como os compiladores funcionam o dia todo, mas esse é um problema real em um caso de uso um tanto básico. Estou apenas pedindo alguma maneira de pelo menos suprimir o erro e continuar por minha conta e risco.

Meu colega de trabalho está tentando remover qualquer arquivo de barril que possa estar nos impedindo de usar exclusões gerais, mas peço que você dê uma olhada no problema que abri originalmente em @ngtools/webpack, onde outro usuário teve o mesmo erro de um componente apenas referenciado em seus testes. https://github.com/angular/angular-cli/issues/3636

O compilador está ciente dos arquivos que não estou pedindo para compilar e está lançando erros irrecuperáveis ​​para situações recuperáveis. simples assim.

Não entendo por que você tem componentes no mesmo diretório que não estão incluídos no projeto.
Eu acho que isso pode ser uma solicitação de recurso, mas atualmente é assim que o compilador funciona, também dizer "funciona em JIT" não é motivo suficiente para pensar que deve funcionar em AOT.
O que eu acho que você precisa fazer é separar esses arquivos do seu aplicativo base em módulos e importá-los através de algum tipo de gerenciador de pacotes, dessa forma ele resolve seus problemas, arruma seu diretório e facilita a manutenção de todos os aspectos

@Toxicable os arquivos não utilizados estão em um módulo npm no estilo de biblioteca. Geralmente, o caso de uso ideal é algo assim:

em @project/angular (nosso módulo npm de código compartilhado) temos todos os componentes, pipes, diretivas e serviços necessários para criar nosso aplicativo base e nos comunicar com nossa plataforma de back-end. Nossos parceiros querem um aplicativo que seja semelhante, mas use uma página inicial diferente ou tenha algum novo componente adicionado. No entanto, a maioria das outras páginas será a mesma e todos os serviços necessários para se conectar à nossa plataforma podem ser os mesmos.

Nossa abordagem para maximizar o código reutilizável foi fazer com que cada parceiro criasse módulos e importasse uma combinação de novas peças e peças compartilhadas do módulo npm. Meu novo HomeModule pode ter uma importação como:

import {
    OverviewComponent,
    ProfileComponent
} from './components/home';

import {
    AuthComponent
} from '@project/angular';

isso então explode no AOT dizendo: Cannot determine the module for class OverviewComponent já que não estamos usando o OverviewComponent de @project/angular.

Como literalmente nenhum arquivo aponta para @project/angular/components/home/overview/component.ts , eu não esperaria que o compilador se importasse com o fato de não ser usado. mas como o arquivo existe dentro do diretório node_modules do nosso projeto, o compilador o encontra, reclama e morre.

Quanto ao JIT funciona !== O AOT funciona, o aplicativo base funciona com o AOT, e as mudanças no parceiro Proof of Concept são incrivelmente pequenas. Não quero dizer que tudo que funciona no JIT deva funcionar no AOT, mas tenho boas razões para acreditar que isso deve acontecer.

Eu tenho outro exemplo em que esse comportamento atual não faz sentido - testes.
Digamos, eu tenho um diretório de recursos some-feature , com some-feature.component.ts e some-feature.component.spec.ts .
Este componente usa projeção de conteúdo, então eu gostaria de testar essa funcionalidade criando um componente de teste dentro do meu arquivo some-feature.component.spec.ts que usa o componente some-feature na view, assim:

@Component({
  selector: 'test-app',
  template: `<some-feature><p>projected content</p></some-feature>`
})
export class TestAppComponent {}

Eu então uso este componente no meu módulo de teste :

  ...
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [TestAppComponent, SomeFeatureComponent]
    })
  })
  ...

Tudo é válido e ótimo, até quando eu executo ng build --prod --aot usando angular-cli, que lança:
Cannot determine the module for class TestAppComponent .

Eu não acho que a AOT deveria se preocupar com arquivos .spec .

A regra geral é: o ngc compilará tudo o que o tsc compilar. E tentará compilar todos os componentes que encontrar. No entanto, o Angular não pode compilar componentes sem um módulo relacionado.

No entanto, poderíamos transformar esse erro em um aviso.

Também tenho componentes de wrapper de teste que são usados ​​apenas para teste e que fazem com que o AOT exploda conforme descrito aqui. Seria bom se o AOT pudesse ignorar todos os componentes que satisfaçam uma expressão curinga como TestComponent* etc.

Tudo bem, então mais informações aqui. Parece que encontramos uma solução alternativa para o nosso caso (não corrige o caso testWrapper). Parece que o verdadeiro problema no nosso caso eram os nossos arquivos de barril. Ao importar QUALQUER COISA de um arquivo de barris, segue a cadeia de todas as coisas reemitidas pelos barris. Como estávamos puxando nossos componentes de um nível superior PROJECT/components , ele estava analisando TODOS os componentes em vez de apenas o que queríamos. Isso provavelmente ainda seria melhor como um aviso, mas posso entender um pouco melhor por que o compilador se preocupava com esses componentes.

vendo o mesmo erro:

$ ./node_modules/.bin/ng-xi18n
Error: Cannot determine the module for class DividerPanel in C:/msweb/studiotouch/src/comps/dividerpanel/DividerPanel.ts!
Cannot determine the module for class EntryPanel in C:/msweb/studiotouch/src/comps/entry/EntryPanel.ts!
Cannot determine the module for class ForgotPass in C:/msweb/studiotouch/src/comps/entry/ForgotPass.ts!
Cannot determine the module for class Footer in C:/msweb/studiotouch/src/comps/footer/Footer.ts!
Cannot determine the module for class Infobox in C:/msweb/studiotouch/src/comps/infobox/Infobox.ts!
Cannot determine the module for class InputNumeric in C:/msweb/studiotouch/src/comps/inputnumeric/InputNumeric.ts!
Cannot determine the module for class InputString in C:/msweb/studiotouch/src/comps/inputstring/InputString.ts!
Cannot determine the module for class Loading in C:/msweb/studiotouch/src/comps/loading/Loading.ts!
Cannot determine the module for class MapAddress in C:/msweb/studiotouch/src/comps/mapaddress/MapAddress.ts!
Cannot determine the module for class Minitab in C:/msweb/studiotouch/src/comps/minitabs/MiniTab.ts!
Cannot determine the module for class Minitabs in C:/msweb/studiotouch/src/comps/minitabs/MiniTabs.ts!
Cannot determine the module for class ModalDialog in C:/msweb/studiotouch/src/comps/modaldialog/ModalDialog.ts!
Cannot determine the module for class Ng2Highcharts in C:/msweb/studiotouch/src/comps/ng2-highcharts/src/directives/ng2-highcharts.ts!

Cannot determine the module for class Ng2Highstocks in C:/msweb/studiotouch/src/comps/ng2-highcharts/src/directives/ng2-highstocks.ts!

Cannot determine the module for class Ng2Highmaps in C:/msweb/studiotouch/src/comps/ng2-highcharts/src/directives/ng2-highmaps.ts!
Cannot determine the module for class simplelistEditable in C:/msweb/studiotouch/src/comps/simplelist/simplelistEditable.ts!
Cannot determine the module for class simplelist in C:/msweb/studiotouch/src/comps/simplelist/simplelist.ts!
Cannot determine the module for class FilterPipe in C:/msweb/studiotouch/src/pipes/FilterPipe.ts!
Cannot determine the module for class FilterPipeEqual in C:/msweb/studiotouch/src/pipes/FilterPipeNot.ts!
Cannot determine the module for class OrderBy in C:/msweb/studiotouch/src/pipes/OrderBy.ts!
Cannot determine the module for class ReplacePipe in C:/msweb/studiotouch/src/pipes/ReplacePipe.ts!
Cannot determine the module for class SortBy in C:/msweb/studiotouch/src/pipes/SortBy.ts!
    at analyzeAndValidateNgModules (C:\msweb\studiotouch\node_modules\@angular\compiler\bundles\compiler.umd.js:24878:17)
    at Extractor.extract (C:\msweb\studiotouch\node_modules\@angular\compiler\bundles\compiler.umd.js:27727:20)
    at Extractor.extractBundle (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extractor.js:40:33)
    at Extractor.extract (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extractor.js:30:34)
    at extract (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extract_i18n.js:7:67)
    at Object.main (C:\msweb\studiotouch\node_modules\@angular\tsc-wrapped\src\main.js:47:16)
    at Object.<anonymous> (C:\msweb\studiotouch\node_modules\@angular\compiler-cli\src\extract_i18n.js:14:9)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
Extraction failed

root@DESKTOP-VEUHFOL /cygdrive/c/msweb/studiotouch

Pia de cozinha angular 2: http://ng2.javascriptninja.io
e source@ https://github.com/born2net/Angular-kitchen-sink
Cumprimentos,

Sean

O i18 não deve percorrer toda a estrutura do projeto e, em vez disso, observar as declarações usadas.

Eu tentei limpar as diretivas que não estão sendo usadas, e a toca do coelho ficou mais profunda:

$ ./node_modules/.bin/ng-xi18n
Error: Error at C:/msweb/ng-skeleton/node_modules/typescript/lib/lib.d.ts:18770:11: Duplicate identifier 'ActiveXObject'.
Error at C:/msweb/ng-skeleton/node_modules/typescript/lib/lib.d.ts:18773:13: Duplicate identifier 'ActiveXObject'.
Error at C:/msweb/ng-skeleton/e2e/app.po.ts:1:38: Cannot find module 'protractor'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/facade/lang.d.ts:12:17: Cannot find name 'Map'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/facade/lang.d.ts:13:17: Cannot find name 'Set'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_init.d.ts:16:18: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/rxjs/Observable.d.ts:68:60: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/rxjs/Observable.d.ts:68:70: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/linker/compiler.d.ts:53:49: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/linker/compiler.d.ts:61:65: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:116:67: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:132:101: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:158:67: Cannot find name 'Promise'.
Error at C:/msweb/ng-skeleton/node_modules/@angular/core/src/application_ref.d.ts:160:101: Cannot find name 'Promise'.

deixe-me acrescentar que tudo está funcionando bem com angular-cli e angular-compiler, então é apenas i18 que não está gostando do meu projeto.

Referência (configuração agradável e limpa): https://github.com/born2net/ng-skeleton

Cumprimentos,

Sean

Mesmo erro para componentes comentados .. componentes não utilizados e comentados para o estágio de desenvolvimento são apenas uma etapa útil para não processar

// two comments aot read:

//  {path: 'about', component: AboutComponent 
// import { AboutComponent } from './about';

@kirjai ngc compila todos os arquivos dentro de um diretório de origem. não importa se você está importando ou não.

@DzmitryShylovich que eu entendo, estou apenas dizendo que não acho que o AOT deva se preocupar com esse arquivo neste caso .. em minha mente, pular arquivos .spec durante a compilação AOT é o caminho a percorrer. Mas claramente há algo que está impedindo a equipe de fazer isso, eu entendo.

Como alternativa, talvez colocar os arquivos .spec no mesmo diretório que a entidade para a qual os testes são escritos não deve ser sugerido pelo guia de estilo?

Também encontro essa mensagem de erro (e algumas outras) por causa do nosso código de teste e AOT em combinação.

Eu posso recomendar este artigo . Ele explica como certas mensagens de erro podem ser provocadas e como corrigi-las.

Considerando que as pessoas se depararão com esse problema exato se seguirem o guia de teste oficial e criarem seu aplicativo com AOT, você pode atualizar o guia?

(Se alguém procurar uma resposta sobre RouterLinkStubDirective )
_Você pode corrigi-lo adicionando um módulo "fictício":_

/**
 * Needed so that `aot` build is working. But it isn't used throughout our tests and/or app.
 */
@NgModule({
    imports: [
        AppModule
    ],
    declarations: [
        RouterLinkStubDirective,
        RouterOutletStubComponent
    ]
})
export class FakeRouterModule {
}

A propósito, ele também tenta determinar o módulo para classes abstratas:
export abstract class AsyncTransform extends AsyncPipe implements PipeTransform { ... }

"Erro: Não é possível determinar o módulo para a classe AsyncTransform"

Adicioná-lo a um módulo também não funciona 😄.
"Não é possível atribuir um tipo de construtor abstrato a um tipo de construtor não abstrato."

isso está acontecendo para algumas classes também.

Err: Não é possível determinar o módulo para a classe AppGlobalModalComponent

export class CustomGlobalModalComponent extends AppGlobalModalComponent {}

@gestj como @Phmager apontou, módulos fictícios não são uma correção para todos os casos. Além disso, eles são uma correção bastante complicada, já que você acaba compilando código que não deseja ou precisa.

Para o nosso caso, corrigimos o problema de uma maneira diferente. Movemos nossos componentes compartilhados para um npm lib e ignoramos node_modules em nosso tsConfig. Eu mencionei acima que isso ainda não funciona, mas apenas porque estávamos usando arquivos de barril. Se você apontar diretamente para cada classe necessária dentro de node_modules, ela ignorará as outras. No entanto, assim que você aponta para um barril, ele lança o erro para os arquivos não utilizados no mesmo barril.

Isso não é o ideal, pois mata todos os nossos maravilhosos arquivos de barril, mas pelo menos é previsível.

Ainda esperando que esse erro seja rebaixado para um aviso

Ótimo trabalho feito na equipe Angular até agora.
Estamos usando muito o Angular em nossos projetos e depois de um ano tentando entender todas essas coisas interessantes do Angular2+, aqui está minha descoberta:
1- Angular é massivo e lento, você quer torná-lo rápido? use AOT e LazyLoading e gzip suas coisas.
2- Você quer fazer um lazyLoad em um componente? NÃO, você seria capaz de carregar lentamente uma rota, então se o seu aplicativo for enorme, mas apenas uma página, aproveite o tamanho do pacote de 8mg.
3- Você quer usar AOT ?? AOT é buggy e difícil de cumprir e não usar montes de recursos javascript/es6 e provavelmente reescrever muito do seu código.
4- Você está usando AOT bem? Tudo bem , agora dê uma olhada no seu pacote final, agora é ainda maior que @angular/compiler mais seus componentes não AOTed , muito bem.

5-Como parte do benefício Angular2+, agora você pode usar o gzip, caso não soubesse como usá-lo antes, agora que o Angular é massivo, você aprenderá melhor :) estamos vendendo gziping como uma opção para otimizar o código Angular2 :)

@xe4me Por favor, mantenha a discussão neste tópico relevante para o problema em questão, em vez de apenas um discurso geral contra a estrutura.

build:dev em https://github.com/AngularClass/angular2-webpack-starter converte automaticamente uma string em uma matriz de strings para corresponder a uma definição de função, build:aot mostra o erro. Durante o desenvolvimento, parece que são necessárias compilações AOT frequentes.

Eu tenho o mesmo problema e encontrei uma solução, talvez funcione também para você.

Meu cenário foi o seguinte:

Tenho um MapPipes.ts, contendo dois Pipes.

Um dos Pipes foi usado no meu módulo, o outro não. Assim, não registrei o segundo na parte "declaration:" do meu decorador @NgModule . O problema aconteceu com este segundo.

Eu registrei também isso (apesar de não ter sido usado), e agora funciona.

Minha sugestão é alterar o compilador angular de forma que ele tente encontrar módulos apenas para as entidades angulares realmente usadas.

Eu tenho recebido esse erro com uma classe abstrata que extends NgClass . A remoção da herança parece corrigir esse problema, mas obviamente cria outros problemas.

@DzmitryShylovich @kirjai este é apenas um problema com TestComponents em um arquivo de especificação se você exportá-los. E como eles geralmente só devem ser usados ​​dentro do mesmo arquivo, não há necessidade de exportá-los. Problema resolvido para mim.

Honestamente, isso é ridículo, eu realmente não tenho mais nada a dizer sobre isso além do fato de que estou muitas horas e ainda não consigo obter algo que funcione no JIT trabalhando com AOT (devo deixar claro que este é apenas um dos cerca de meia dúzia de edições até agora).

@cwmrowe tudo bem, mas e se você tiver um que está sendo reutilizado em vários arquivos de especificação? Isso parece quebrado para ser honesto.

No meu caso, eu estava trabalhando em 2 projetos diferentes no mesmo aplicativo principal Angular 2. Eu tenho 2 pastas com o nome de nossos clientes, digamos some-domain.com e some-other-domain.com . O aplicativo é exatamente o mesmo para os 2 projetos e difere apenas em um pouco de estilo e alguns componentes personalizados menores. Hoje preciso compilar o aplicativo para o cliente A, e mais tarde quero compilar para o cliente B. No código é tão fácil quanto alterar 1 linha de código para mim:

import {CustomModules} from './some-domain.com';
// import {CustomModules} from './some-other-domain.com';

Eu simplesmente descomente qualquer domínio que eu queira compilar também e funciona.

Temos o mesmo problema com herança e classes abstratas e não encontramos nenhuma solução. Temos alguns componentes que estendem um componente abstrato. No JIT tudo funciona muito bem, mas no AOT os módulos para componentes abstratos não podem ser encontrados e não é possível declarar componentes abstratos em um módulo.

Atualmente, não temos outra solução além de evitar padrões de design oop e usar código redundante.

@jabaa remove a anotação @Component da sua classe abstrata

@DzmitryShylovich Quando removo @Component o construtor não é herdado. Eu tenho que injetar todos os injetáveis ​​em todos os componentes em vez do componente abstrato. Isso é código redundante. Quando mudo o construtor e os serviços da classe abstrata, tenho que adeptar todos os componentes filho.

Atualmente trabalhamos em torno disso implementando todos os métodos abstratos com métodos fictícios e criando um módulo fictício para todos os componentes abstratos. Mas então alguém pode esquecer de substituir o método fictício. Isso é tudo apenas um trabalho ao redor.

@jabaa qual versão você usa? construtor deve ser herdado independentemente de @Component .

@bigjetplane Não tenho certeza de onde está o problema, mas quando removo @Component recebo um erro de que as dependências do componente não foram encontradas. Até onde eu sei DI só funciona para classes com decoradores Angular. Então, quando eu removo os decoradores, as dependências não são injetadas. Usamos Angular 4.

@jabaa está quebrado com jit ou aot, ou ambos?

@bigjetplane Aqui está o plunker com o problema. Existe uma classe abstrata com decorador e tudo funciona em jit. Quando você remove o decorador da classe abstrata, o aplicativo não pode renderizar porque nem todas as dependências podem ser carregadas: Can't resolve all parameters for App: (?).

Esse é o nosso caso de uso. Temos uma classe abstrata com construtor e injeções. Queremos apenas substituir alguns métodos abstratos nos componentes filhos

O exemplo dado não funciona no aot. A diferença entre aot e jit é um grande problema para nós. Estamos desenvolvendo com jit. A compilação de produção é com aot. Então estamos desenvolvendo uma semana com jit sem erros e avisos e depois da semana queremos um build de produção e pegamos muitos erros do nada. Eu prefiro um switch para jit, onde posso habilitar erros aot. Uma compilação jit precisa de 10 a 20 segundos. Uma compilação aot precisa de 25 minutos.

@tbosch Alguma palavra sobre como mudar isso para um aviso? Parece que, desde a minha última visita, muitos outros entraram na conversa com suas próprias anedotas, e eu queria saber se você poderia nos dar uma atualização.

Obrigado!

Eu também tenho o mesmo problema.

No meu caso eu estava trabalhando em 2 projetos diferentes, mas incluindo os componentes comuns através de um projeto interno de biblioteca angular adicionado como dependência em package.json.

Como é um projeto de biblioteca, os componentes não utilizados do repositório de componentes estão lançando o erro abaixo ao compilar uma compilação de produção AOT.

ERROR in Cannot determine the module for class FullPageErrorComponent in C:/users/amra6003/projects/git/refadmintoolui/n ode_modules/refcommonui/src/app/component-library/error/error.component.ts! Cannot determine the module for class SelectCountryComponent in C:/users/amra6003/projects/git/refadmintoolui/node_modul es/refcommonui/src/app/component-library/select-country/select-country.component.ts! Cannot determine the module for class DateRangeSelectorComponent in C:/users/amra6003/projects/git/refadmintoolui/node_m odules/refcommonui/src/app/component-library/date-range-selector/date-range-selector.component.ts!

Parece que eu tenho que criar um módulo para cada componente e usar :(

Qualquer correção para este problema ajudará muito.

Também espero uma solução para isso. Aparentemente, o uso de componentes de stub para teste é pretendido pelos desenvolvedores do Angular - portanto, excluí-los da compilação de maneira limpa também precisa ser possível. Por enquanto estou usando a solução sugerida pelo gestj (definindo um módulo falso no qual o componente stub é declarado).

Portanto, ao usar stub-components para teste, você deseja nomear seu componente com o sufixo spec.ts como whatever.component.spec.ts . Dessa forma, o tsc ignorará esses arquivos (dado que está excluído em seu tsconfig) e, portanto, também será ignorado pelo ngc.

EDIT: acontece que este é um erro diferente, resultante de um bug no ngtools/webpack. Esse ticket foi aberto aqui: https://github.com/angular/angular-cli/issues/6228


Nova diversão nesta frente para minha empresa. Em uma tentativa recente de atualizar nossos sistemas para a v2.4.10, acabei com algumas dúzias de erros desse tipo:

ModuleNotFoundError: Module not found: Error: Can't resolve '../../../../../../../../$_gendir/src/components/spinner/component.ngfactory'

Parece estar registrando todos os componentes em nossa biblioteca compartilhada que não estão sendo usados ​​pelo aplicativo atual. Isso é estranhamente semelhante ao erro para o qual eu abri o ticket originalmente.

Eu não tenho certeza do que mais podemos fazer sobre isso. Tentamos abordar cada componente que precisamos da biblioteca compartilhada diretamente (sem usar nenhum arquivo index.ts , pois eles pareciam puxar todos os arquivos referenciados no índice) e mover toda a biblioteca compartilhada para node_modules.

Por que o compilador precisa saber sobre cada componente angular na minha pasta node_modules ? Mesmo que precise lê-los para construir seu mapa, não deve se preocupar se eles têm ou não um módulo!

@swimadude66 , sim, encontramos isso trabalhando com nossa biblioteca https://github.com/WealthBar/a2d3 . Mesmo que não forneça componentes de modelo (apenas diretivas), a biblioteca ainda deve ser construída com o compilador AoT ou não funcionará com compilações AoT quando usada.

@chrisnicola Você está dizendo que a biblioteca deve ser pré-compilada com AoT antes de ser publicada? porque isso implicaria que a biblioteca tem seus próprios módulos, o que parece realmente contra-intuitivo. Como está, a biblioteca são arquivos ts descompilados, que extraímos como qualquer outro arquivo em nosso projeto. A coisa toda é então compilada com o plugin @ngtools/webpack para webpack.

Vale a pena notar que mesmo o erro original para este ticket foi "consertado" do nosso lado até a v2.1.1 simplesmente eliminando todas as referências aos arquivos index.ts. Essa correção não parece mais funcionar para a v2.4.10.

Ah entendi, sim, interpretei mal o seu problema. Você não está puxando uma biblioteca compartilhada pré-compilada via NPM aqui, você tem uma biblioteca TS local em seu projeto. Eu entendi corretamente agora?

Eu concordo que deve "apenas funcionar" e você está correto, definitivamente parece o mesmo problema em que está encontrando componentes que não têm módulo no aplicativo. Uma solução possível seria usar um tsconfig.json específico da compilação AoT que exclui os arquivos e pastas que não são necessários para a compilação AoT.

Consegui resolver todos os nossos problemas relacionados a esse erro.
O problema (e solução) aparece ao exportar.

Tínhamos um componente que era usado apenas para testes. Ele foi exportado de outro arquivo para que pudesse ser reutilizado - isso causou problemas ao executar nosso destino i18n.

Para resolvê-lo, apenas declaramos um módulo (certifique-se de exportá-lo também):

@NgModule({ declarations: [MyUnusedComponent] })
export class IgnoreModule {}

Nosso outro componente que causou um erro foi um componente não utilizado que invadiu o i18n.
Estava sendo exportado para ser captado pela ferramenta i18n, mas isso causava o mesmo erro do outro componente.

@Component({
    template: `
        <div i18n="some context@<strong i="13">@some</strong> key">some text to be translated</div>
    `
})
export class LocalisationComponent {}

Novamente, usando a técnica IgnoreModule, poderíamos facilmente ignorá-la.

@NgModule({ declarations: [LocalisationComponent] })
export class IgnoreModule {}

@UtopianStorm que não é uma solução. Foi mencionado acima que ter um "UnusedModule" não é apenas difícil de dimensionar, mas também cria um módulo inteiro de arquivos de origem que não devem ser incluídos no pacote de distribuição.

@Phmager Você já encontrou uma solução alternativa para o problema do componente abstrato? Estou puxando meu cabelo.

@swimmadude66 Não é uma solução no sentido de que é definitivamente uma solução alternativa - mas supera o erro.
Não tenho certeza de como seria difícil dimensionar, pois a técnica pode ser aplicada toda vez que o problema surgir.

Ele vai desordenar seu pacote de distribuição, mas isso importa? Do estado de Angular, eu meio que presumi que já estaria cheio de nossos arquivos de especificações.
De qualquer forma, é uma abordagem muito mais limpa do que acessar diretamente as entranhas da pasta node_modules, você não concorda?

Pelo menos no caso de uso para o qual originalmente abri o ticket, nem é uma solução viável. Não é viável para todas as equipes de parceiros manter uma lista de componentes compartilhados não utilizados à medida que avançamos.

Além disso, enviar essencialmente 2 aplicativos completos simplesmente porque o compilador é excessivamente rigoroso é um compromisso que não estou disposto a fazer. Angular já é bastante grande, e não posso justificar o envio de um módulo inteiro de componentes não utilizados apenas para deixar seu compilador opinativo feliz.

@swimmadude66 Entendo. Se você acha que adicionar outro módulo faz uma diferença tão grande, é melhor eu dar uma olhada novamente - porque eu não estava defendendo apenas a criação de um módulo não utilizado para compartilhar por todo o projeto, mas um módulo para cada componente que eu tive que liberar do compilador excessivamente estrito - potencialmente dusins.

Vale a pena notar que nossa base de código compartilhada é bastante grande, então um módulo não utilizado seria de longe o maior módulo do aplicativo. Nossa situação não é 100% típica, mas ainda dentro dos limites da razão para ser apoiada, acredito.

Honestamente, depois de 5 meses vendo esse ticket ir a lugar nenhum, estamos analisando outras opções, incluindo apenas matar nosso repositório de código compartilhado

Estou enfrentando exatamente o mesmo problema que você, @swimmadude66 . O fato de que este não é um aviso suprimivel é ridículo.

Querida equipe Angular, há algo que você possa fazer sobre isso?

@DzmitryShylovich Como excluo um arquivo mock.ts que não estou usando? Eu tentei colocá-lo em tsconfig.app.json , tsconfig.json e tsconfig.ng-cli.json e nenhum parecia funcionar.

Enfrentando o mesmo problema com exatamente o mesmo caso de uso - usamos Rollup, portanto, componentes não utilizados nem chegam ao pacote final.

Por favor, reprima isso! É um grande incômodo, e está parando o trabalho.

Acabei de me deparar com isso também, tão frustrante.

@mlakmal e outros, que estão recebendo erros em códigos como

export class CustomGlobalModalComponent extends AppGlobalModalComponent {}

Remova a anotação @Component de AppGlobalModalComponent ou declare AppGlobalModalComponent (se for utilizável) em NgModule

Eu criei uma diretiva mock para usá-la em meus testes. E obtenha esse problema com a compilação AOT. Eu não quero importar essa diretiva simulada em módulos simples. Por favor, corrija isso.

Eu me pergunto se a tag "freq1: low" nesta questão é devido ao fato de que AoT é uma dor de cabeça tão espetacular para começar a trabalhar, que as pessoas nem estão se incomodando com isso? É um pouco inacreditável que um problema tão simples, mas doloroso, tenha recebido essencialmente zero feedback dos principais contribuidores do Angular.

De qualquer forma, existe uma maneira de excluir arquivos que não foram especificamente mencionados. Se você tiver um padrão de nomenclatura (por exemplo .spec.ts , .abstract.ts , .stfu-aot.ts ), poderá criar um arquivo tsconfig.json separado para AoT e usá-lo em vez disso: ngc -p tsconfig-aot.json . Neste arquivo você pode usar o "exclude": ["./app/**/*.stfu-aot.ts"] para excluir os arquivos. É irritante, mas deve funcionar.

Edit: O acima não parece funcionar com classes abstract que herdam de um componente. Yay :(

Acabei de me deparar com isso também, tão frustrante. Quando compilar aot, o componente comum não pode ser compartilhado em outro aplicativo

alguns dos casos comuns para este problema, evite adicionar @Component à sua classe de serviços:

// just remove this 
@Component({
    providers: []
});
@Injectable()
export class serviceClass {}

Eu tenho um cenário em que estou injetando um serviço em um serviço. À primeira vista, parece uma coisa fácil de implementar, basta adicionar @Component. Portanto, os documentos do Angular devem ser atualizados para mostrar esta solução para serviços complexos: Para resolver esse problema, removi @Component. No construtor do Service eu adicionei:
constructor(@Inject(ExampleService) private exampleService: ExampleService)

você não precisa adicionar @Component() decorador a nenhum serviço. Apenas @Injectable()

FWIW Eu tenho um MockXYZComponent que estende XYZComponent um componente de aplicativo, mas é usado apenas em especificações (tem o mesmo seletor e, portanto, não pode ser importado para AppModule ).

Este não é um caso de uso válido?

@alastair-todd não tenho certeza se entendi o que você quer dizer. Se você usar componente como componente, adicione @Component() decorador. Se você usar o componente como base - apenas para herdar dele, mas não como um componente, não precisará usar o decorador - mas apenas herdar e usar o decorador no "sucessor".
Sobre o teste de unidade - não posso responder, provavelmente você precisa criar um TestModule especial? Não faço testes unitários no momento.

@tytskyi Eu entendi que a herança do decorador não era suportada. Isso mudou recentemente?

o caso de uso é simular um subcomponente como abaixo. Ambos precisam da diretiva @Component para selecionar o seletor.

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                AppModule
            ]
        }).overrideModule(AppModule, {
            remove: {
                declarations: [SelectionToolComponent]
            },
            add: {
                declarations: [MockSelectionToolComponent]
            }
        }).compileComponents();

No entanto, isso gera o erro de compilação OP AOT.

Meu ponto de vista é um caso de uso válido, caso em que a compilação AOT é excessivamente zelosa e/ou ignora as especificações como parte do projeto.

Talvez minha solução ajude alguém: acabei de criar um módulo fictício que declara todo o componente simulado. Este módulo não é importado por nada - apenas mantém o compilador AoT feliz. Conseqüentemente, nenhum dos componentes simulados faz parte do código compilado. Não é o ideal, mas problema resolvido.

Eu adoraria ouvir sobre qualquer solução melhor.

Isso é tão estranho e embaraçoso que este problema foi aberto em dezembro de 2016 e ainda tem esse problema. Eu converti a estrutura de todo o meu aplicativo para usar a compilação aot. Eu tenho 4 módulos que são carregados com preguiça e mais de 60 componentes. O compilador reclama apenas de alguns componentes (conforme o que o erro sugere) que tenho certeza que já fazem parte das declarações de um dos módulos carregados com preguiça, o que é meio estranho para mim.

Está até dando erros em componentes que já fazem parte de algum módulo.

Mesmo problema

O compilador do Angular procura o conjunto de arquivos que você entregou ao tsconfig - portanto, excluir arquivos de lá deve excluí-los desta verificação.

Isso é realmente irritante :(

@alastair-todd desculpe, perdi a notificação da sua pergunta em muitas outras notificações. Você está certo -
A herança do decorador não é suportada.

Veja a resposta de @robwormald

O compilador do Angular procura o conjunto de arquivos que você entregou ao tsconfig - portanto, excluir arquivos de lá deve excluí-los desta verificação.

Então você pode tentar fazer convenções para nomes de arquivos fictícios, como: selection-tool.component.mock.ts . Em seguida, exclua através

"exclude": [
    //... other excludes
    "**/*.component.mock.ts"
]

acidentalmente clicou no botão errado, desculpe!

+8 meses e ainda é um problema. Mesmo problema aqui ERROR in Cannot determine the module for class PasoFooterComponent

Eu acho que é vital que os desenvolvedores do Angular ignorem esses arquivos.

Se alguém puder me dar dicas de onde posso encontrar esse código, ficarei feliz
para consertar eu mesmo. Isso é um incômodo que incomoda muito. Correu para ele
novamente ontem.

Se alguém acha que isso é um recurso e não um bug, que tal ter um sinalizador
por esta?

Quarta-feira, 9 de agosto de 2017 às 2h40, Leonardo Vidal [email protected]
escrevi:

+8 meses e ainda é um problema. Mesmo problema aqui ERROR in Cannot
determine o módulo para a classe PasoFooterComponent


Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/angular/angular/issues/13590#issuecomment-321082545 ,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AEM6r7FOTLcicWJN3Oijw2pwKTLGL6cFks5sWM61gaJpZM4LSAwS
.

@samirotiv Tem alguma reprodução?
Como disse @robwormald

O compilador do Angular procura o conjunto de arquivos que você entregou ao tsconfig - portanto, excluir arquivos de lá deve excluí-los desta verificação.

Tive o mesmo problema mas consegui resolver. Acabei de ver como o ts transpila meu aplicativo, por exemplo

"tsc": "rimraf out-tsc/app && tsc -p ./src/tsconfig.app.json",

E notei que o typescript não compilou meus módulos carregados com preguiça porque usei a opção "arquivos" tsconfig

Estou recebendo este erro na classe abstrata (sem decoradores)

Comecei a me deparar com esse mesmo problema recentemente.

+1 para alterar o erro para aviso.

Parece uma solução fácil. Por que o atraso?

Este é um requisito básico - deixe arquivos não referenciados.
Essa restrição é um problema para projetos maiores. Por favor, altere isso para aviso.

Há casos em que você publica um pacote que oferece suporte a diferentes versões de angular. e espera-se que o usuário escolha um deles.

Por exemplo, um pacote que fornece arquivos para HttpClient (Angular >= 4.3 usuários) e Http (Angular < 4.3 usuários)

Atualmente, o ngc compila todos os arquivos dentro de um diretório de origem, não importa se você os usa ou não! ou a compilação falha.

O que eu fiz foi isso:

Salvei todos os meus componentes stub/mock com uma extensão .mock.ts e atualizei o array tsconfig.app.json "exclude" assim:

...
  "exclude": [
    "test.ts",
    "**/*.spec.ts",
    "**/*.mock.ts"
  ]
...

AOT agora pula a compilação desses arquivos

Estamos fazendo uma biblioteca npm com componentes comuns que deveriam ser usados ​​não todos de uma vez e chateados por esse problema durante a compilação AoT, caramba... A única solução atm é criar uma espécie de UnusedComponentsModule no projeto host - simplesmente ridículo! Também precisa de NO_ERRORS_SCHEMA ou vai jurar sobre outros componentes que podem ser usados ​​dentro de seus componentes não utilizados e se você os declarar, você terá outro problema em que não pode declarar o mesmo componente em dois módulos (relacionado a # 10646).

Meu módulo atual:

import {NgModule, NO_ERRORS_SCHEMA} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ReceiverPageComponent} from 'cb-web-platform';

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    ReceiverPageComponent
  ],
  schemas: [
    NO_ERRORS_SCHEMA // IMPORTANT: need that for AoT compilation
  ]
})
export class UnusedComponentsModule {
}

Isso realmente deveria ser um aviso. Estou tentando compartilhar uma base de código também e estou enfrentando esse problema de componentes que não fazem parte de um ngmodule.
O problema aqui está exatamente no mesmo nível de uma variável não utilizada que não é um erro; no máximo é um aviso.

É fácil quando é o seu código. Quando é um problema de alguma biblioteca angular NPM (algum código morto), é realmente uma dor de cabeça :)

Alguém pode explicar por que não pode ser um aviso em vez de um erro?

No meu caso, eu só quero extrair langs preferencialmente de componentes que estão conectados ao ngModule e apenas ignorar aqueles que não estão. Eu tenho uma pasta principal do aplicativo com componentes base e pastas específicas do aplicativo que às vezes substituem componentes do aplicativo principal quando tento extrair esse componente substituído com xi18n, ele gera um erro Cannot determine the module for class... que, na minha mente, poderia ser apenas ignorado e extração poderia ser continuado sem usar esse componente não utilizado.

Uma coisa que eu posso pensar que pode ser um problema é que eu ainda uso essa classe que está definida nesse arquivo de componente defeituoso como base para criar o componente substituído, então ele precisa ser compilado, mas eu simplesmente não preciso desse componente causa da anotação, pois você não pode usá-la no componente de substituição. Pelo menos eu acho que você não pode porque eu tenho que recriar essas anotações em componentes derivados para fazê-los funcionar.

@Xesenix , pelo menos, deve ser uma opção. Como determineModule = false / true. Agora é banana.

Retornarei em 01/11/2017.

Responderei sua mensagem após meu retorno.
Em casos urgentes, envie uma cópia do seu e-mail para
assuntos técnicos para [email protected] , caso contrário
[email protected]. Outro funcionário examinará seu e-mail
aceitar.

Observação: esta é uma resposta automática ao seu "Re:
[angular/angular] Angular2 AOT compilation - "Não é possível determinar o módulo
para classe (... muitos componentes que não são usados)" (#13590)" enviado em
23/10/2017 08:13:17.

Esta é a única notificação que você receberá enquanto
essa pessoa está ausente.

Como isso ainda não foi corrigido quase 1 ano depois? Puxando meu cabelo para fazer o AOT funcionar, mas esse problema me faz bater em uma parede de tijolos.

Obrigado @rahul-sivalenka-wtc pela solução!
Consegui resolver meu problema com sucesso excluindo "**/*.mock.ts" no meu tsconfig.app.json como você descreve ❤️

Que bom que pude ajudar 😊

Eu também encontrei o problema. Mas para mim parece que acabei de colocar erroneamente o caminho da importação do dodule

alguma solução? (não é possível determinar o módulo para o componente angular 5)

https://stackoverflow.com/questions/47119135/cannot-determine-the-module-for-component-angular-5

Isso provavelmente deve ser severity3: broken . Para aqueles de nós com vários destinos de compilação e dependências polimórficas (muitos casos de uso dos quais foram apresentados acima), esse problema impede que as compilações funcionem sem uma configuração de compilação complicada e maluca.

alguma boa solução para este problema ainda? O IgnoreModule é apenas uma solução alternativa, mas não uma solução muito boa para esse problema. mudar o erro para um aviso seria ótimo!

Nossa solução foi adicionar uma função transform a @ngtools/webpack que passa arquivos por pré -processamento e componentes ifdef ing com base em várias configurações de tempo de compilação. Muito, muito feio, mas funcional.

Tente importar todas as dependências angulares primeiro em app.module.ts e depois importe os componentes.

` ---------------- Primeiro módulos de dependência de importação -----------------------
importe { BrowserModule } de '@angular/platform-browser';
importe { CommonModule } de "@angular/common";
importe { NgModule } de '@angular/core';
import { RouterModule, Routes } de '@angular/router';
importe { HttpModule } de '@angular/http';
import { ReactiveFormsModule } de '@angular/forms';
importe { BrowserAnimationsModule } de '@angular/platform-browser/animations';

-------------Em seguida, importar módulos de serviço ------------------------

import { ApplyFormPostService } de './Services/apply-form-post.service';
import { NavBarColorService } de './Services/nav-bar-color.service';

----------------------- Finalmente importe os módulos do componente ----------------------- -

import { AppComponent } de './app.component';
import { HeaderComponent } de './components/header/header.component';
import { CareerComponent } de './components/career/career.component';
import { HomeComponent } from './Components/home/home.component';`

De alguma forma, isso resolveu o erro de compilação AOT jogando Não é possível determinar o módulo para a classe --- no modo de produção

@KarthikSamyak este problema não é sobre pessoas que têm classes que DEVEM estar em um módulo. Isso é sobre nós com bibliotecas de componentes, que são propositadamente excluídas de todos os módulos. Eles são códigos não utilizados que devem ser ignorados pelo compilador. Em vez disso, o compilador lança um erro irrecuperável quando os descobre.

Realmente deve ser uma mudança simples transformar esse erro em um aviso, mas por algum motivo levou MAIS DE UM ANO e foi recentemente movido de pri_col1 para pri_col2 no roteiro.

Estou cada vez mais frustrado com a equipe Angular por sua completa falta de resposta a esse problema. Nossa empresa acabou desistindo de usar as bibliotecas de componentes completamente, optando por copiar os arquivos manualmente. Isso está longe de ser o ideal, pois agora temos problemas com componentes quase idênticos, mas não compartilhados.

Equipe Angular, se você ainda ler este problema, por favor, apenas adicione uma configuração de compilador para "ignoreUnusedComponents" e deixe-nos continuar usando este framework.

Ok, eu encontrei o lugar https://github.com/angular/angular/blob/master/packages/compiler/src/aot/compiler.ts#L605 @tbosch ei, você pode ajudar aqui e dizer como fazer isso para ser um aviso corretamente? Não é possível ver nenhum aviso lançado nesse compilador AoT, apenas erros. A opção do compilador pode ser adicionada, conforme sugerido acima.

Essa questão é uma dor em projetos complexos. Meu caso particular é https://github.com/angular/angular/issues/13590#issuecomment -331820496

Nosso caso de uso é o mesmo. Queremos ter uma biblioteca de módulos/componentes para criar aplicativos realmente fáceis e ter a capacidade de substituir/estender os estranhos quando necessário.

Também estamos tendo problemas de outra forma: se quisermos substituir 1x componente dentro de um módulo, criamos um novo módulo e importamos os componentes que ainda queremos nele:

import { HeaderComponent, SidebarComponent } from '@mylibs/layout';
import { FooterComponent } from './footer.component';

@NgModule({ declarations: [ HeaderComponent, SidebarComponent, FooterComponent ] })
export class MyLayoutModule { }

@NgModule({ imports: [ MyLayoutModule ] })
export class AppModule { }

O erro é: `HeaderComponent é declarado em 2 módulos: lib/module.ts e app/module.ts
Ser um aviso, pelo menos, nos permitiria seguir em frente :(

Acabei de perceber - Feliz aniversário para esta edição :)

Um ano depois, e ainda não podemos mudar isso para um aviso. Ridículo.

Literalmente, também me deparei com esse problema. O compilador tenta puxar um mock que é usado apenas em testes e falha porque não faz parte do módulo principal. Se ele sabe que não precisa do arquivo, deve ser um aviso no máximo.

Por favor, corrija isso. Faça disso um aviso!
Minha experiência geral com a construção angular 5 aot é menos que estelar.

Após alguma discussão https://gitter.im/angular/angular?at=5a551f565a9ebe4f756843b2 chegamos à conclusão de que precisamos criar um componente por módulo, pois parece que o módulo é apenas contexto de compilação e não uma maneira de coletar coisas juntas. .

Isso está tomando o tamanho de um livro de história.

@Xesenix ... o contexto e a organização são 2 partes do todo.

Apenas no caso de alguém ainda estar preso com isso, você pode fazer com que esse script seja executado como script de pós-instalação como uma solução alternativa

const replace = require('replace-in-file');
const filesToFix = [
    {
        files: 'node_modules/@angular/compiler/esm2015/compiler.js',
        from: ['throw syntaxError(messages.join(\'\\n\'));'],
                // Actually this does nothing , just leave it blank should do
        to: [`console.warn(\'Angular compiler warning\');\n\t\tconsole.warn(messages.join(\'\\n\'));`]
    }
]

filesToFix.forEach((i) => {
    try {

        const changes = replace.sync(i);
        if (changes.length > 0) {
            console.log('Modified files:', changes.join(', '));
        }
    }
    catch (error) {
        console.error('Error occurred:', error);
    }
});

O compilador angular usará a saída do tsconfig, então altere _tsconfig.app.json_ para excluir os arquivos que você não deseja incluir
por exemplo
"exclude": [ "test.ts", "**/*.spec.ts", "**/*.mock.component.ts", ]

@andela-andrewmakenzi isso já foi sugerido antes, mais adiante neste bate-papo gigantesco (absolutamente sem vergonha em não ler tudo). No entanto, surgem problemas se você depender de um componente em uma biblioteca que usa arquivos barril (index.ts). Se você importar qualquer componente de um arquivo barril, o compilador tentará carregar todos os componentes referenciados nesse arquivo barril e reclamará que eles não estão em um módulo. Isso torna difícil empacotar bibliotecas de componentes reutilizáveis, que é basicamente o ponto principal da arquitetura de componentes em primeiro lugar.

Sua solução funciona muito bem para pessoas que têm componentes simulados e estão recebendo esse erro quando não estão executando testes. Mas se a sua organização (como a minha) tentou criar uma biblioteca de componentes comuns e obter apenas os que precisamos para qualquer projeto, a exclusão do TSC infelizmente não o ajudará.

@andela-andrewmakenzi: Sua sugestão parece ajudar por enquanto, o problema anterior é que eu tenho um componente para teste de unidade como (.spec) e não gostaria que ele fosse incluído para compilação AOT (e talvez algum componente simulado que Eu nem gostaria de tê-lo na minha projeção) Talvez isso tenha sido abordado de alguma forma na versão posterior do Angular, eu acho :)

Mas meu caso foi que eu tenho muitos componentes novos que nem foram referenciados no NgModule então por enquanto devemos ter uma convenção de nomes para ele e excluí-los no tsconfig.json , o que não é muito agradável por enquanto

Isso é realmente ridículo. Temos um módulo NPM compartilhado exportando alguns tubos/diretivas e, a menos que você importe TUDO, ele falha com esse erro idiota. Deve realmente ser alterado para um aviso e não deve quebrar a compilação.

Na minha opinião, cada componente deve estar em seu próprio NgModule . Não é tão assustador criar outro NgModule para cada componente. (Como o que @angular/material fez)

Eu acho que é realmente um problema virtual. Também não podemos ver nenhuma razão para ter algo apenas pela metade. Não é um NgModule , não é um pacote, não está fora da árvore do aplicativo ... algo que parece código morto.

Portanto, com o novo @angular/cli (1.7.0+), mesmo IgnoreModule de alguma forma não resolve esse problema.

Na minha opinião, cada componente deve estar em seu próprio NgModule

Você ainda tenta escrever testes de unidade? Este bug está tornando a criação de auxiliares de teste meio problemática.

@sarunint Em aplicativos de tamanho empresarial como aquele para o qual abri originalmente este ticket, seriam centenas de módulos, com importações muito complicadas para lidar com diretivas e componentes dependentes. Isso tem uma correção muito simples: se o compilador não conseguir encontrar um módulo para um componente, lance um aviso e elimine-o em um tree-shake.

A verdadeira razão pela qual isso é tão irritante é o fato de que as limas de barril se tornam mais um perigo do que uma vantagem. É conveniente centralizar suas importações, mas não se você estiver se comprometendo a incluir todos os componentes exportados em todos os aplicativos que usam sua biblioteca.

@dborisenkowork Não tenho certeza se você não viu (ou se não funciona para o seu caso de uso), mas a solução fornecida pelo @rahul-sivalenka-wtc funciona perfeitamente.

Alguém recentemente mudou de angular 4 para angular 5 e notou que alguns de seus componentes que estão realmente sendo declarados em módulos estão lançando esse erro?

@novologic-clay que erro? O tópico é longo, você está se referindo ao erro original
Compilação Angular2 AOT - "Não é possível determinar o módulo para a classe (... muitos componentes que não são usados)" ?

@andela-andrewmakenzi Sim e não. É o mesmo erro impresso ao tentar compilar, mas o componente que está reclamando certamente está incluído em um módulo. Estou migrando de 4.3.6 para 5.2.4, e não estava recebendo esse erro para este componente específico porque atualizei minha versão do angular e fiz uma compilação AOT no 4.3.6 logo antes de começar a migrar como um teste de fumaça .

@novologic-clay você pode compartilhar seus erros de console?

... o objetivo final deve ser usar a opção tsconfig.json "noUnusedLocals": true que elimina tudo o que não é utilizado.

@andela-andrewmakenzi

ERROR in : Cannot determine the module for class InlineAddComponent in /Users/claygarland/CatalsytConnect/frontend/Talon/src/app/core/component/input/inline-add/inline-add.component.ts! Add InlineAddComponent to the NgModule to fix it.

Este é um aplicativo corporativo e existem dezenas de camadas de módulos e importações, mas este é o código que realmente declara o componente:

**COMPONENT:**
import {Component, Inject, Input} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
import {ActivatedRoute} from '@angular/router';
import {BaseForm} from '../../form/form/BaseForm';
import {FormDataService, FormDataServiceProvider} from '../../form/form/FormDataService';
import {BaseApi} from '../../../api/BaseApi';

@Component({
    selector: 'inline-add',
    templateUrl: './inline-add.component.html',
    styleUrls: ['./inline-add.component.scss'],
    providers: [
        FormDataServiceProvider
    ]
})
export class InlineAddComponent extends BaseForm {

    @Input() title = 'Entity';
    @Input() formName;

    protected service: BaseApi;

    constructor(
        protected route: ActivatedRoute,
        protected formDataService: FormDataService,
        public dialogRef: MatDialogRef<InlineAddComponent>,
        @Inject(MAT_DIALOG_DATA) public data: {
            form: string,
            title: string,
            service: BaseApi,
        },
    ) {
        super();
        this.title = data.title;
        this.formName = data.form;
        this.service = data.service;
    }

    submit() {
        super.onSubmit(res => {
            this.dialogRef.close(res.data[0]);
        });

    }

    onCancel() {
        this.dialogRef.close(false);
    }

}

**MODULE:**
import { NgModule } from '@angular/core';
import {SharedModule} from '../../../shared/shared.module';
import {InlineAddComponent} from './inline-add/inline-add.component';


@NgModule({
    imports: [
        SharedModule,
    ],
    declarations: [
        InlineAddComponent,
    ],
    exports: [
        InlineAddComponent,
    ],
    entryComponents: [
        InlineAddComponent,
    ]
})
export class FormInputsModule { }

Também digno de nota é que quando executo este aplicativo no ng serve, o componente funciona bem.

Componentes falsos usados ​​por testes de muitos componentes reais não devem estar em um módulo; Eles são apenas incluídos no TestBed de componentes testados.
Esse erro é estúpido. Por favor, resolva isso como é durante de um ano.

remova a "exportação" para que o ts não a leve para a compilação.

@tony-kaplan Você não pode fazer isso se tiver noUnusedLocals em seu tsconfig, nem se quiser usar o código em casos de teste ou similares.

Meu Deus.... realmente ninguém da equipe principal encontrou uma solução adequada para isso?
Estou usando a opção exclude por enquanto, mas ainda é uma solução temporária. Não consigo pensar em algo que funcione para todas as situações... mas eu realmente preciso...

@gabrielalan A solução fácil é transformar esse erro em um aviso. A melhor solução é adicionar um sinalizador que permita tratar isso como um aviso ou erro. Não é falta de soluções, é falta de implementação de qualquer uma delas.

Oh garoto! Tanto para uma estrutura corporativa ...

@atom-morgan de qual solução você está falando?

@netlander Este

Realmente, nada posso fazer sobre o erro "Não é possível determinar o módulo para a classe DaterangepickerDirective"?

Alguém me ajuda também? Depois desse post megazord!

Não concordo em adicionar as novas exclusões tsconfig.app.json a esta Diretiva! Como posso compilar com --aot param sem esse problema?

Meu caso de uso https://github.com/angular/angular/issues/23475
Estou criando uma biblioteca de validadores e não quero criar módulo para cada diretiva de validação, tudo o que quero é apenas poder agrupar diretivas de validação para o pacote npm para que o usuário possa instalar e importar apenas validadores que ele precisa para o NgModule. Também não quero criar um módulo para todos os validadores porque todos eles serão empacotados no pacote final, o que é um enorme desperdício de tamanho.

Fico feliz em criar PR para corrigir o problema.

@anjmao que é incrivelmente semelhante ao motivo pelo qual abri isso em primeiro lugar. Como solução para uma biblioteca pequena, descobrimos que esse erro não ocorre se você não usar arquivos barril (index.ts). Parece que se você importar 1 componente/diretiva de um índice, ele tenta encontrar um módulo para todas as outras exportações do arquivo de índice.

Obviamente, ainda acredito que isso deve ser um aviso, já que os arquivos de barril são super convenientes. No entanto, se o seu caso de uso não puder esperar mais um ano por essa correção, você poderá contorná-lo assim.

Solução alternativa que estou usando para minha biblioteca compartilhada de componentes/diretivas/pipes: crie um módulo fictício simples que faça referência a todas as declarações de classe. Você não precisa usar este módulo em seus aplicativos reais, ele só precisa existir no disco. Ex:

import { NgModule } from '@angular/core';

@NgModule({
    imports: [],
    declarations: [
        MyComponent,
        MyPipe,
        MyDirective,
        ...
    ],
})
export class DummyModule {
}

Existe uma razão pela qual ainda não corrigimos esse problema?

A solução "Faça um aviso" não é adequada? Um membro da equipe principal pode comentar sobre isso?

No meu caso, as coisas funcionaram bem com NG 5, CLI e AOT. Mas depois de atualizar para o NG 6, recebo um erro semelhante para um componente não utilizado. Na verdade o componente é usado através de um serviço injetado no outro componente. Eu tenho muitos componentes semelhantes construídos e usados ​​da mesma maneira. Mas apenas um tem o problema um ao atualizar para o NG CLI 6.0 e 6.0.1 mais recente

E acabou que, em uma das referências, tenho a referência do arquivo no caso errado. Tenho um index.ts para exportar todos os componentes no mesmo diretório. eu tinha
export * from './dateTimePicker.component'
enquanto deveria ter sido:
export * de './datetimePicker.component';

Aparentemente, o NG CLI 6 é mais restrito para casing mesmo no Windows, enquanto o NG CLI 1.x é um pouco relaxante.
Obviamente, essa restrição é boa e correta, portanto, a mesma base de código pode funcionar bem no Linux, que diferencia maiúsculas de minúsculas por padrão.

Outro caso de uso para isso:

Typescript permite que você configure vários caminhos de resolução com a variável paths em tsconfig.json . Ex:

{
    ...
    "paths": {
        "~src/*": ["src/*", "src-gen/*"]
    }
}

Permitindo que você importe coisas como esta:

import { NgModule } from "@angular/core";
import { ExampleComponent } from "~src/example.component";

@NgModule({
    declarations: [
        ExampleComponent
    ],
})
export class ExampleModule {}

Se você está gerando um componente dentro src-gen que o desenvolvedor pode "substituir" criando outro dentro da pasta src , o mesmo erro começa a acontecer com o componente (agora não utilizado) dentro src-gen (que não precisa ser excluído, pois pode ser estendido pelo overrider).

Outro caso de uso potencial:

Componentes específicos do ambiente. Eu os despi para a produção.

const environmentComponents = production ? [] : [
  DevOnlyComponent,
];

@NgModule({
  declarations: [
    ...environmentComponents,
  ],
})
export class ExampleModule {
}

Consegui fazer todo o resto funcionar com componentes específicos do ambiente e é isso que me impede. 😪

Estamos enfrentando esse problema ao implementar um mecanismo para personalização de compilação (os componentes são trocados por diferentes projetos Angular CLI) que se parece muito com o cenário descrito por @tiagodws (incluindo a extensão do componente original).

Existe alguma atualização/opinião de uma equipe central sobre esse assunto?

Mais de um ano depois de abrir esta edição, minha nova abordagem é minimizar o uso de arquivos barril. Se você usar caminhos TS como ~components/button/component em suas importações em todos os lugares, as importações não utilizadas serão ignoradas. Se esse componente não utilizado for referenciado em um arquivo de barril, ele será lançado.

Isso ainda não é incrível para bibliotecas reutilizáveis, pois você precisa acessar todos os componentes da biblioteca com caminhos mais longos, em vez de apenas importar dessa biblioteca de nível superior. Por que, oh, por que isso não pode ser apenas um aviso?

Isso também parece que pode ser ajudado (ou pelo menos relacionado a) tremor de árvore, onde qualquer código não incluído especificamente em um módulo é excluído do pacote final.

opção exclude não para um mock pipe:

@Pipe({ name: 'translate' })
export class MockTranslatePipe implements PipeTransform {
    transform(value: string): string {
        //Do stuff here, if you want
        return value;
    }
}

Meu tsconfig.app.json excluiu este arquivo:

"exclude": [
        "test.ts",
        "**/*.mock.ts",
        "**/*.spec.ts"
    ]

No entanto, quando executo ng-xi18n --i18nFormat=xlf2 --outFile=./assets/i18n/messages.xlf, ele ainda reclama:

Não é possível determinar o módulo para a classe MockTranslatePipe em src/test/translate.service.mock.ts! Adicione MockTranslatePipe ao NgModule para corrigi-lo.

Meu problema era que eu tinha o nome de uma classe em 2 componentes diferentes copiando e colando lol! Mais tarde o mesmo erro por não se importar Boa prática faz caras perfeitos! exitos...
Assinatura: Satoshi Nakamoto: v

Semelhante a @yuezhizizhang , ainda tenho esse problema, mesmo depois de adicionar um glob para mocks ao caminho tsconfig.app.json exclude .

É quase irritante que isso não tenha sido resolvido quase dois anos após o ticket inicial; este é um caso de uso comum que está quebrando as compilações. Ao escrever testes, o desenvolvedor deve idealmente criar mocks para pipes, serviços e assim por diante, a menos que. Se você optar por fazer isso, sua compilação será interrompida. Caso contrário, seus arquivos de especificação fazem referência aos componentes/tubos/etc reais, o que leva a testes muito bem acoplados.

Alguém da equipe Angular poderia sugerir como contornar isso? A criação de um módulo fictício para simulações é realmente a única opção? Esse é um hack ruim, em vez de algo que devemos aceitar como melhor prática.

o problema persiste. Também adicionei o arquivo que desejo pular a compilação (classe abstrata) à seção de exclusão de tsconfig.app.json e ainda recebo:

Não é possível determinar o módulo para a classe MapElementBaseComponent em .../map-elements/map-element-base.component.ts! Adicione MapElementBaseComponent ao NgModule para corrigi-lo.

Eu me livrei desse problema depois de verificar as importações

ср, 14 нояб. 2018 г., 15:13 Daniel Groh [email protected] :

o problema persiste. Eu também adicionei o arquivo que desejo pular a compilação
(classe abstrata) para a seção de exclusão de tsconfig.app.json e eu
Ainda assim:

Não é possível determinar o módulo para a classe MapElementBaseComponent em
.../map-elements/map-element-base.component.ts! Adicionar MapElementBaseComponent
para o NgModule para corrigi-lo.


Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/angular/angular/issues/13590#issuecomment-438641324 ,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AQb6kpWdkakUF8JVvea8Hy42tAnTKTuzks5uvAjvgaJpZM4LSAwS
.

Quando o TypeScript é restrito, importando Angular, na compilação AOT, componentes não usados ​​de uma biblioteca e lançando este erro ... Verifique se os componentes / módulos não usados ​​não fazem sentido ...

image

Ao excluir a pasta da biblioteca onde está o módulo e os componentes não usados, o aplicativo é iniciado em strict-aot bem - mas certamente não faz sentido excluir esta pasta manualmente

Este erro é absolutamente ridículo. Eu tinha um módulo que especificava componentes em um objeto, assim:

const landingComponents = {
    'landing-root': LandingComponent,
    'get-notified': GetNotifiedComponent,
    'typed-component': TypedComponent,
    'sticky-bar': StickyBarComponent,
};

então tentei alimentar o módulo com declarations: Object.values(landingComponents) , entryComponents: Object.values(landingComponents) .

Adivinha o que ... o compilador AOT precisa ver os componentes listados em uma matriz ... caso contrário, se eu passar de outra maneira, recebo este horrível "Não é possível determinar o módulo para a classe".

Por mais que eu ame Angular, o compilador AOT parece uma sopa caótica de encantamentos mágicos.

Já foi dito algumas vezes, mas a solução é 1 componente por módulo para isso e não tenho certeza se você notou dos PRs para o Angular, mas isso foi mesclado recentemente e pode ser de interesse para este tópico: https://github.com/ angular/angular/puxar/27481

Esta edição completa hoje 2 anos 🎉

Ainda assim, nem mesmo uma palavra da equipe principal sobre por que isso não poderia ser apenas um aviso.

@tiagodws lol há quanto tempo você está esperando para postar isso? Você definiu um lembrete?

Apenas um FYI
Meu problema era o mesmo que https://github.com/angular/angular/issues/13590#issuecomment -389113560
As importações são aparentemente sensíveis a maiúsculas e minúsculas no modo AOT

@peterdeme ... JavaScript diferencia maiúsculas de minúsculas (e caminhos como strings são os mesmos ... = baseado em Linux, não em Windows).

Ei, pessoal, estou voltando para uma comemoração tardia da idade da edição de 2 anos. Há muita conversa cruzada sobre possíveis causas para as pessoas, incluindo as seções include e exclude de tsconfig.json , então eu só quero esclarecer qual é a raiz do problema para este fio.

Se você criar uma biblioteca de componentes reutilizáveis ​​e adicionar arquivos de barril ( index.ts ) para facilitar as importações, o compilador Angular será interrompido quando você usar qualquer um deles. Isso ocorre porque assim que você importar qualquer coisa desse barril (digamos, @shared/components ), ele tentará encontrar o módulo para CADA COMPONENTE. Mesmo se você especificar os componentes específicos que deseja (por exemplo import { SharedToastComponent } from '@shared/components'; ), o compilador ainda procurará o módulo para cada componente exportado e lançará um erro (não um aviso) sobre os componentes ausentes.

Obviamente, existem soluções alternativas.

  1. Pare de usar arquivos de barril. Isso fica confuso rapidamente, pois todos os componentes precisam ser totalmente especificados
  2. Use um ExtrasModule e não use o módulo em nenhum lugar. Isso funciona bem para pessoas que têm componentes necessários apenas para teste, mas não tão bem para pessoas que desejam extrair de uma biblioteca de componentes

No entanto, como o uso de qualquer uma dessas soluções alternativas resulta exatamente no mesmo código de saída após a vibração da árvore, é óbvio que os outros componentes não PRECISAM ser incluídos em um módulo usado. Tudo o que estou pedindo com esse problema de 2 anos é transformar esse erro em um aviso mais apropriado. Faz sentido, já que a compilação ainda seria bem-sucedida se continuar.

Esperamos que em 2019 a equipe Angular faça algo sobre esse problema muito antigo e muito chato. 🤞

@swimmadude66 ... você não mencionou a maneira de criar um módulo lib real e adicioná-lo a um aplicativo Angular via tsconfig.json ... como: "paths": {"ng-demo": ["./packages/ng-demo/src/index.ts"]} e usá-lo via importação como import { DemoModule } from 'ng-demo'; . Desta forma elimina a necessidade de publicar a lib em um repositório npm público/privado, mas ainda respeita a função nativa desse módulo lib. Assim, ele funciona de forma transparente em seu aplicativo e você não tem problemas.

Ter um erro em cada stub de componente é a coisa mais irritante. Todo mundo está testando/escrevendo especificações, certo? Portanto, os erros de stub do componente devem afetar a todos. Não estou dizendo que a questão do barril é menos irritante. Só estou dizendo que nem todo mundo está fazendo os barris. Mas todos deveriam estar fazendo especificações. Portanto, o problema das especificações deve ser a maior motivação para a equipe principal corrigir isso. Atualmente, é rotulado como "Frequência baixa", mas deve ser "Frequência alta", porque qualquer pessoa que faça testes de unidade atingirá esse problema.

Isso nem é consistente no AOT. Angular CLI não dá erros ao executar com serve (que por padrão usa AOT), mas dá erros executados com build.

Eu entendo que este não é o repositório CLI Angular, mas certamente o comportamento em torno disso é estranho.

Mesmo com a solução alternativa de criar um módulo simulado, agora o "ng build" falhará se um escritor de teste de unidade de interface do usuário esquecer de adicionar um único componente simulado a um módulo simulado.

Acima significa que o teste de unidade de interface do usuário é atualmente um elemento de risco para o pipeline de implantação de CI/CD!

Nós realmente queremos ter que explicar para as pessoas mais altas na cadeia alimentar que os testadores de unidade Angular podem quebrar compilações inteiras de implantação com uma única omissão trivial? Não. As pessoas que gerenciam desenvolvedores Angular e que tomam decisões sobre qual framework usar para o próximo projeto não devem se perguntar sobre esse tipo de coisa.

Como um paliativo: por que não apenas tornar o erro que aparece em "ng build" mais informativo para os escritores de teste: ou seja, adicionar texto adicional para o efeito de "se este é um componente simulado usado no teste: adicione-o a um módulo simulado nesse arquivo conforme (este url)"

Como seus testes unitários de escrita de desenvolvedores Angular amigáveis ​​chegaram aqui:

a) IMHO é uma prática de código DRY para criar um arquivo "auxiliar" para colocar componentes simulados, serviços, etc. que todos os arquivos .spec usam. No entanto, esta prática executa o testador neste cenário de bug.

b) Todos os arquivos .spec podem importar este arquivo "auxiliar" sem a necessidade de um "módulo simulado" que não tem relevância para o código de teste real. Os componentes simulados são úteis no estado em que se encontram, sem participação em um módulo simulado que não tem nenhuma função no ambiente de teste de uma especificação.

Claro que a solução alternativa é trivial ... mas apenas encontrar esse bug através da pesquisa do Google, ler e digerir o tópico e soluções úteis não foi.

Acabei de adicionar isso ao final do arquivo auxiliar que contém os componentes simulados (entre outras coisas):

/*
  mock components
  !! Each mock component added to this file *must* be added to the "MockTestModule", see below !!
*/
@Component({
  selector: 'app-mock-component',
  template: '<span>mock widget</span>'
})
export class MockComponent {}

/*
  This is an unused module to resolve the ng build error:
    'ERROR in : Cannot determine the module for class MockComponent
    in C:/code/myRepo/src/assets/test/test-resources.ts!
    Add MockComponent to the NgModule to fix it.'

  Reference: https://github.com/angular/issues/13590

  Each mock component added to this file *must* be added to the "MockTestModule"
*/
@NgModule({
  declarations: [ MockComponent ],
})
export class MockTestModule {}

Observe que o arquivo acima na realidade é bastante grande ... o "MockTestModule" está enterrado no final do arquivo auxiliar ...

...Espero que não tenhamos que escrever uma entrada package.json para "ng build" que intercepta a chamada e insere uma mensagem de console "hey UI unit testers, you add your mock component to the mock module?" cutucar.

Aqui está o que resolveu o problema para mim. Minha estrutura é a seguinte:

├── icons.module.ts
├── index.ts
├── icon
│   ├── icon.component.html
│   ├── icon.component.ts
│   └── icon.module.ts
└── icon-indicator
    ├── icon-indicator.component.html
    ├── icon-indicator.component.ts
    └── icon-indicator.module.ts

Em icons.module.ts eu tinha:

import { IconComponent } from './icon/icon.component';
import { IconIndicatorComponent } from './icon-indicator/icon-indicator.component';

export { IconIndicatorComponent, IconComponent };

@NgModule({
  /* this was all fine */ 
})
export class IconsModule {}

O index.ts tinha:

export * from './icons.module';

Estou assumindo que o problema foi que o compilador não analisou os módulos ícone e indicador de ícone antes de encontrar os componentes correspondentes e, portanto, lançou o erro Cannot determine the module for class . Este projeto é ng 5. Só recebi o erro ao consumi-lo em um projeto ng 7.

A solução é baixar as exportações um nível. Então eu removi a declaração de exportação em icons.module.ts e as movi para:

icon.module.ts:
export { IconComponent };
...

icon-indicator.module.ts:
export { IconIndicatorComponent };
...

e ajustado index.ts :

export * from './icons.module';
export * from './icon/icon.module';
export * from './icon-indicator/icon-indicator.module';

Espero que isso ajude alguém.

Acho que o novo renderizador de hera resolverá alguns problemas com o AOT. Como você pode ver nas solicitações de pull e problemas, a equipe angular está se concentrando no ivy, então não há sentido em fazer algo sobre esse problema no angular 6.

Acho que o novo renderizador de hera resolverá alguns problemas com o AOT.

Eu amo ouvir isso em cada questão.

Também estou tendo esse problema com angular 7.2.0 e angular-cli 7.3.0

ERROR in : Cannot determine the module for class ModalMockComponent in /Users/user/repos/angular-skeleton/src/app/shared/modal/modal.component.mock.ts! Add ModalMockComponent to the NgModule to fix it.
Cannot determine the module for class TranslatePipeMock in /Users/user/repos/angular-skeleton/src/app/shared/pipes/translate.pipe.mock.ts! Add TranslatePipeMock to the NgModule to fix it.

Por exemplo, eu tenho um TranslatePipe e um TranslatePipeMock dentro do meu Shared Module . TranslatePipe está incluído no módulo, o mock pipe não.
translate.pipe.mock.ts é para fins de teste de unidade, então posso importar este arquivo para cada teste de unidade.

Mas agora minha compilação falha
ng build --prod

Como nós consertamos isso?

Atm eu tenho uma solução alternativa que resolve isso

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "types": []
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts",
    "**/*.mock.ts"
  ]
}

É difícil determinar o status atual desse problema a partir de uma breve análise dos comentários. Concordo que isso é um problema (design ruim). Qual é o plano para corrigi-lo? É fácil ou difícil?

@rrmayer o status deste problema é provavelmente apenas "esperar por hera", como acontece com quase todos os problemas "atuais".

Nós só queremos que isso seja alterado de "erro" para "aviso", para que nossos projetos realmente compilem... Isso é tão difícil?

@Terrafire123 ... pode haver muitas relações com ferramentas de teste ou construção, por exemplo, que se baseiam realmente no fato de que esse caso leva ao erro, portanto, a alteração do aviso pode ser um problema sério.

Não tenho esperança de que seja corrigido para o compilador atual :D

Talvez devêssemos pelo menos ter a opção de mostrar um erro ou um aviso. A quebra de builds por causa de componentes que não fazem parte de um módulo de propósito é bastante irritante.

As importações não utilizadas podem causar este erro.

import { UnusedImportComponent } from "./used-somewhere-else-or-not.component";

Parece que a palavra-chave 'export' ao lado da classe determina de alguma forma que a classe que tem o decorador @Component aplicado, deve ser incluída em algum módulo. Quer você importe a classe do componente e declare diretamente em testes ou declare em, por exemplo, CoreMocksModule e depois importe o módulo, tudo não importa.

Há uma solução embora! Digamos que temos nosso componente stub declarado assim:

@Component({
  selector: 'app-user-stub-component',
  template: ''
})
export class UserStubComponent {}

Temos que remover a palavra-chave 'export' mas de alguma forma ainda temos que exportar o componente para usá-lo no módulo de teste/teste. Faça isso deste modo:

@Component({
  selector: 'app-user-stub-component',
  template: ''
})
class UserStubComponent {}

export default UserStubComponent;

Agora, em todos os lugares quando você importa o stub, temos que evitar colchetes como segue:
import UserStubComponent from 'path'

Espero que funcione. Para mim, resolve problemas de compilação AOT.

No meu caso, eu consertei. O problema era com a carcaça. Eu usei letras maiúsculas para pastas, mas a importação automática do código VS importou o caminho com letras minúsculas.

@renilbabu03 JS diferencia maiúsculas de minúsculas.

No meu caso, consertei para meus testes de unidade, onde zombei do canal de tradução.

Eu mudei o export class para default export :

import { PipeTransform, Pipe } from '@angular/core';

@Pipe({
  name: 'translate'
})
class TranslatePipeMock implements PipeTransform { // <-- NOT: "export class TranslatePipeMock implements PipeTransform"
  public name = 'translate';

  public transform(query: string): any {
    return query;
  }
}

export default TranslatePipeMock;

Alguma correção para isso?
Eu tentei export default <class> mas quando executo ng serve --aot , ele lança um erro: Valor inesperado 'null' exportado pelo módulo .

É muito frustrante.

@redplane Por que você quer fazer isso? Quero dizer a exportação default .

A menos que eu import um ativo exported , por que o Angular se importa se o arquivo existe?

Na maioria das vezes, estou refatorando um componente ou removendo componentes e só quero comentar as referências de componentes obsoletos, como fiz nos dias do CommonJS. Isso seria bastante seguro, já que eu nunca uso arquivos de barril porque já fui queimado muitas vezes nessa frente, e ter Angular me forçando a me comprometer a remover fisicamente os ativos do meu projeto é simplesmente inaceitável quando estou no fundo do pescoço uma fase de prototipagem...

Estou preso no Angular 6 porque sou o único desenvolvedor trabalhando neste projeto e seria um inferno refatorar as coisas para obter as ferramentas estáveis ​​mais recentes no meio de ter que lançar novos recursos ... pelo menos seria ótimo se o Angular 6+ pudesse ser corrigido com um sinalizador do compilador para desabilitar esse comportamento ...

No meu caso, estou tendo uma configuração de projeto de biblioteca angular. Em um dos meus componentes dentro da biblioteca, declarei alguns enums, para usar esses enums no meu projeto de aplicativo que estava importando com um caminho relativo para o diretório de projetos na raiz do meu aplicativo.

Esta é a razão pela qual o compilador angular queria que meu componente de biblioteca fosse declarado em qualquer um dos ngModules do projeto do aplicativo.

Para resolver esse erro, tenho que declarar meus enums no arquivo public-api.ts , bem como usá-los no projeto do aplicativo com uma importação direta da biblioteca e não com um caminho de importação relativo.

Por exemplo:
Nome do projeto da biblioteca: components-lib
Nome do projeto do aplicativo: demo-app

Para usar quaisquer interfaces, classes, enums , etc declarados dentro do projeto da biblioteca, importe-os com um caminho direto:

import { SearchEnum } de 'components-lib';

e não faça
import { SearchEnum } from '../../../projects/components-lib/path-to-your-component';

Espero que isso ajude alguém no futuro, pois passei horas encontrando isso sozinho.

Tendo um problema para manter a compatibilidade para uma biblioteca construída com o ng 9 que eu queria que as pessoas executando o ng 8 pudessem usar.

Eu ofereço através da biblioteca algumas classes utilitárias que seus componentes podem estender. Nessa cadeia de classes pai, algumas delas são abstratas e com ng 9 precisam ter um @Directive({ selector: 'random' }) para serem compatíveis com ng 8.

Então eu quase consegui escapar... MAS:

Cannot determine the module for class NgxSubFormComponent in /........./node_modules/ngx-sub-form/ngx-sub-form.d.ts! Add NgxSubFormComponent to the NgModule to fix it.`

Eu não exponho nenhum módulo dentro da biblioteca, as pessoas devem apenas estender as classes que oferecemos. Mas eu não quero que eles importem as classes pai em seus módulos (não faria sentido).

Então, estou preso e vou apenas cortar uma versão de alteração que exige que as pessoas atualizem para o ng 9 em vez de ter compatibilidade com versões anteriores

Olá a todos, desculpem o silêncio sobre este assunto.

ngc no View Engine, por design, gera arquivos ngfactory para cada componente na "compilação" - ou seja, o conjunto completo de arquivos TS definidos pelo seu tsconfig. É assim que o TypeScript
em si funciona - compila todos os arquivos definidos por um arquivo tsconfig. ngc está apenas fazendo processamento extra em cima disso.

Portanto, se um @Component estiver presente nessa compilação e o ngc puder vê-lo (o que significa que é de nível superior e exportado), o ngc tentará compilá-lo. Não há como contornar isso a não ser garantir que o ngc não compile o arquivo que declara o componente em primeiro lugar.

A maneira correta de fazer isso é definir o escopo do seu tsconfig. Por exemplo, você pode ter um tsconfig de nível superior para seu editor, que inclui todos os arquivos e, em seguida, um tsconfig.app.json para a compilação do aplicativo especificamente, que herda da configuração do editor e exclui os arquivos de especificação. Apenas a configuração do aplicativo seria compilada com ngc.

Projetos (cada tsconfig é um "projeto") devem ser estruturados de forma que um componente e seu módulo sejam sempre compilados juntos.

Em Ivy, as mesmas regras ainda se aplicam em grande parte, com várias pequenas diferenças:

  • Por padrão, Ivy tentará compilar _any_ @Component , independentemente de ser exportado.
  • Não é mais um erro, no Ivy, ter um componente sem módulo. No entanto, você ainda receberá erros de verificação de tipo de modelo se esse componente tentar usar outros componentes/diretivas em seu modelo, pois sem um módulo nada mais será visível para esse componente.
  • É possível dizer ao compilador Ivy para ignorar um componente ou módulo específico e deixá-lo até o tempo de execução, adicionando um sinalizador jit: true ao decorador.

@alxhub Fico feliz em saber que não é mais um erro!

Eu entendo que o ngc tentará compilar qualquer coisa que o tsc faria, e que o tsc compilará qualquer coisa dentro de seu escopo. Dito isto, o requisito de que um componente seja adicionado a um módulo é 100% uma preocupação angular, portanto, removê-lo do escopo do seu projeto datilografado parece chutar a lata no caminho. Além disso, com padrões como arquivos barril sendo comuns, pode ser difícil remover realmente um único arquivo da compilação, sem TAMBÉM removê-lo de qualquer reexportação ao longo do caminho. É por isso que as chamadas para simplesmente "excluir esses componentes" acima foram muitas vezes recebidas com insatisfação.

Em relação à limitação restante com o ivy (os erros de modelo em componentes sem módulos), é pedir demais que sejam avisos também? Entendo que pode ser mais difícil (ou impossível) se a verificação de tipo ocorrer antes que o componente seja identificado como sem módulo, mas me parece um aviso ao longo das linhas de Warning: ExampleUnusedComponent does not belong to an NgModule, and will be excluded from the output captura com precisão a ideia de que o componente (e quaisquer outros referenciados por ele) não serão incluídos, a menos que sejam adicionados a um ngModule.

No geral, estou muito animado para ver o movimento nessa questão e ansioso para testar meu caso de uso original com as novas alterações no compilador ivy!

Esta página foi útil?
0 / 5 - 0 avaliações