Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular class is not an Angular module

When I build my Angular library, publish it to npm, and use it as a dependency in another project, whenever I try to import on of my module classes into my app.module.ts, and get this error Class TekButtonModule is not an Angular module. I have followed steps from multiple different sites on how to create, build, and publish angular libraries, and I can't figure out why it won't recognize the class as a valid module class.

In my app.module.ts, this is how I am importing the module:

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

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

My library project follows the standard directory structure outlined by Angular. I did not change anything with the build, or path settings when I setup the library project. My built library project has a bundles, esm5, esm2015, fesm5, fesm2015, lib (where my custom modules, and components are), as well as a package.json, public-api.d.ts (exports everything in the lib directory), README.md, tek-angular-uimodules.d.ts (exports the public api), and a tek-angular-uimodules.metadata.json file.

Is there some extra configuration that it needed that isn't setup by default to get modules to work correctly?

Here is my button module class:

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

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

Here are some of the files that are generated when I build the project: 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 {
}

If I import the generated javascript module file from the esm5 directory manually in my app.module.ts file, then it works just fine. But I have to manually do that, when it should just work with the standard module import that WebStorm auto imports for me like any other package.

This is the generated module js file under the esm5 directory:

/**
 * @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

Any help is appreciated. I can provide more code, and screenshots if needed.

This is the error I get when trying to import my module: enter image description here

like image 705
Mark Lisoway Avatar asked Jul 19 '19 22:07

Mark Lisoway


2 Answers

So I figured out what was causing my specific issue. It was two things. Point two is the direct reason for my issue, point one was making much more confusing to debug.

  1. In order to test my built package, I would run ng build, and then cd into the built project in the dist directory, and run npm pack. I would then install my built package as a file dependency in an entirely separate project to ensure I did everything correctly. What I found out was (or I'm assuming) that there was a caching mechanism going on even when doing local file dependency installations. This caching seemed to be tied to the file name of the tgz file that is generated from npm pack. This caching was causing the very first version to be constantly reinstalled not matter how many changes I made to the built library. The fix, for me, was to simply rename the tgz file to something different each time. You should also change the library version number, and that should also work.
  2. My file structure looked like this:
src
- public-api.ts
- lib
-- button
--- index.ts
--- public-api.ts
--- button.component.ts
--- button.module.ts
-- another-module
-- yet-another-module

The public-api.ts file directly in src looked like this:

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

The public-api.ts, and the index.ts file under src\lib\button looked like this:

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

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

I had assumed that by adding the index.ts files to each directory, the export line in the root public-api.ts would find the index file, and export the files accordingly, but somewhere along the line, this implicit resolution does not work, and, instead, an explicit export is needed. The fix was to change export * from './lib/button' to export * from './lib/button/index.ts' or export * from './lib/button/public-api.ts'.

Point two was the direct reason for my issue, point one just made it really confusing when trying to debug.

like image 127
Mark Lisoway Avatar answered Oct 07 '22 13:10

Mark Lisoway


So I had the same issue with a different solution, so I thought I would share it here.

I had just updated my library to Angular 9. And everything seemed fine except the strange "Class my-module is not an Angular module" error.

What worked for me was to up tsconfig.lib.ts file with:

...
"angularCompilerOptions": {
  ...,
  "enableIvy": false
}
like image 27
Kristoffer Abell Avatar answered Oct 07 '22 12:10

Kristoffer Abell