javascript - Angular sınıfı bir Angular modülü değildir


Angular kütüphanemi oluşturduğumda, npm üzerine yayınladığımda ve başka bir projede bağımlılık olarak kullandığımda, app.module.ts dosyama modül sınıflarımdan birini aktarmaya çalıştığımda şu hatayı alıyorum: Class TekButtonModule is not an Angular module. Angular kütüphanelerini oluşturma, derleme ve yayınlama hakkında farklı sitelerden adımları takip ettim, ama sınıfı geçerli bir modül sınıfı olarak tanımamasının nedenini çözemedim.

Benim app.module.ts dosyamda, modülü şöyle ithal ediyorum:

import { TekButtonModule } from "tek-angular-uimodules";

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

Kütüphane projem, Angular tarafından belirtilen standart dizin yapısını takip ediyor. Kütüphane projesini kurarken build veya yol ayarlarında hiçbir değişiklik yapmadım. Derlenmiş kütüphane projemde bir bundles, esm5, esm2015, fesm5, fesm2015, lib (özel modüllerim ve bileşenlerim burada), ayrıca bir package.json, public-api.d.ts (lib dizinindeki her şeyi dışa aktarır), README.md, tek-angular-uimodules.d.ts (public api’yi dışa aktarır) ve bir tek-angular-uimodules.metadata.json dosyası bulunuyor.

Modüllerin doğru çalışması için varsayılan olarak yapılandırılmamış ekstra bir ayar gerekiyor mu?

İşte benim buton modülü sınıfım:

import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { TekButton } from "./button";

@NgModule({
  declarations: [
    TekButton
  ],
  exports: [
    TekButton
  ],
  imports: [
    CommonModule
  ]
})
export class TekButtonModule {}

İşte projeyi derlediğimde oluşturulan dosyalardan bazıları: tek-angular-uimodules.d.ts:

/**
 * Generated bundle index. Do not edit.
 */
export * from './public-api';
public-api.ts
export * from "./lib/button";
export * from "./lib/button-group";
export * from "./lib/nav-bar";
./lib/button/button-module.d.ts
export declare class TekButtonModule {
}

Eğer oluşturulan javascript modül dosyasını esm5 dizininden manuel olarak app.module.ts dosyamda import edersem, o zaman gayet iyi çalışıyor. Ama bunu manuel olarak yapmam gerekiyor, oysa standart modül importu ile, WebStorm'un herhangi bir paket için otomatik olarak import ettiği şekilde, çalışması gerekir.

Bu, esm5 dizini altındaki oluşturulmuş modül js dosyasıdır:

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { TekButton } from "./button";
var TekButtonModule = /** @class */ (function () {
    function TekButtonModule() {
    }
    TekButtonModule.decorators = [
        { type: NgModule, args: [{
                    declarations: [
                        TekButton
                    ],
                    exports: [
                        TekButton
                    ],
                    imports: [
                        CommonModule
                    ]
                },] }
    ];
    return TekButtonModule;
}());
export { TekButtonModule };
//# sourceMappingURL=data:application/json;base64

Her türlü yardım takdir edilir. Gerekirse daha fazla kod ve ekran görüntüsü sağlayabilirim.

Modülümü içe aktarmaya çalışırken aldığım hata bu:

Cevap #1

Yani, belirli sorunumun neye yol açtığını çözdüm. İki şeydi. İkinci nokta sorunumun doğrudan sebebiydi, birinci nokta ise hata ayıklamayı çok daha karmaşık hale getiriyordu.

  1. Oluşturduğum paketi test etmek için, ng build komutunu çalıştırır, ardından dist dizinindeki oluşturulmuş projeye cd ile girer ve npm pack komutunu çalıştırırdım. Daha sonra, oluşturduğum paketi tamamen ayrı bir projede dosya bağımlılığı olarak kurar ve her şeyi doğru yaptığımı doğrulardım. Öğrendiğim (veya varsaydığım) şey, yerel dosya bağımlılığı kurulumları sırasında bile bir önbellekleme mekanizmasının işlediğiydi. Bu önbellekleme, npm pack komutundan oluşturulan tgz dosyasının adıyla bağlantılı görünüyordu. Bu önbellekleme, yapılan tüm değişikliklere rağmen ilk sürümün sürekli yeniden kurulmasına neden oluyordu. Benim için çözüm, tgz dosyasının adını her seferinde farklı bir şey olarak değiştirmekti. Ayrıca kütüphane sürüm numarasını da değiştirmelisiniz, bu da işe yaramalıdır.
  2. Dosya yapım şöyle görünüyordu:
src
- public-api.ts
- lib
-- button
--- index.ts
--- public-api.ts
--- button.component.ts
--- button.module.ts
-- another-module
-- yet-another-module

src içindeki public-api.ts dosyası şöyle görünüyordu:

export * from './lib/button'
// Other exports

src\lib\button altındaki public-api.ts ve index.ts dosyası şöyle görünüyordu:

// public-api.ts
export * from './button.component.ts'
export * from './button.module.ts'

// index.ts
export * from './public-api.ts'

Her dizine index.ts dosyalarını ekleyerek, kök public-api.ts içindeki export satırının index dosyasını bulacağını ve dosyaları buna göre dışa aktaracağını varsaymıştım, ancak bir noktada bu örtük çözümleme çalışmıyor ve bunun yerine açık bir export gerekiyor. Çözüm, export * from './lib/button' satırını export * from './lib/button/index.ts' veya export * from './lib/button/public-api.ts' şeklinde değiştirmekti.

İkinci nokta sorunumun doğrudan sebebiydi, birinci nokta ise hata ayıklamaya çalışırken işleri gerçekten kafa karıştırıcı hale getirdi.

Cevap #2

Yani ben de farklı bir çözümle aynı sorunla karşılaştım, bu yüzden bunu burada paylaşmayı düşündüm.

Kütüphanemi Angular 9'a yeni güncellemiştim. Ve her şey yolunda görünüyordu, sadece garip "Class my-module is not an Angular module" hatası dışında.

Benim için işe yarayan şey tsconfig.lib.ts dosyasını şu şekilde güncellemektir:

...
"angularCompilerOptions": {
  ...,
  "enableIvy": false
}

İlgili makaleler