angular: Error "Please add a @NgModule annotation" in Angular4

I’m submitting a … (check one with “x”)

[X] bug report

Current behavior I have an Angular application which imports a module from another repository.

So my app.module.ts

@NgModule({
  imports: [
    ...
    MyCommonModule,
  ],
  declarations: [...],
  providers: [...],
  bootstrap: [AppComponent]
})
export class AppModule { }

and then in my node_modules I have my common repository (installed with yarn/npm in package.json) with the file file my-common-module.d.ts

@NgModule({
  imports: [...],
  declarations: [...],
  providers: [...],
  exports: [...]
})
export class MyCommonModule {}

This works fine with Angular 2. Now, I delete node_modules and change the version of Angular to 4.0 in the package.json of my app and then yarn again. I build the app with webpack, no errors, and when I run it I get the following error in the browser

Uncaught Error: Unexpected value 'MyCommonModule' imported by the module 'AppModule'. Please add a @NgModule annotation.

Expected behavior I’d expect this to work the same with Angular4 or Angular2.

My question is, do I need to also upgrade the common module to Angular4 for this to work? I thought that this would already be transpiled to js when I import it in my main app module, maybe I’m wrong.

Please tell us about your environment: I tested this with webpack-dev-server

  • Angular version: 2.0.X With 2.0.0 it’s working, with 4.0.0 it’s not.

  • Browser: I tested this in Chrome and FF.

  • Language: I’m using typescript 2.2.2

  • Node (for AoT issues): node --version =

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 10
  • Comments: 70 (8 by maintainers)

Most upvoted comments

Please add a small reproduction.

You can also get this error if you declare a component in the imports array.

What are your dependencies on your MyCommonModule? How did you specify dependency on angular? It is among dependencies or peerDependecies? Anyway if you have something like this "@angular/core": "^2.4.3" in your “library” and "@angular/core": "^4.0.1" in your application it wont work. NPM creates two versions of angular in your node_modules and if NgModules is defined in 2 files they are not same.

You have to set version in your “library” to "@angular/core": ">=2.4.3" or to "@angular/core": "^4.0.0". You should check subdirectory of your lib in node_modules if there is directory named node_modules and if there is @angular/core.

If it is there, that is the problem. I hope it helps, if not i can explain better 😃.

I can confirm that mentioned solutions from above are working. Problem is caused from using symlink after running npm link [your-lib] if there is populated node_modules folder in library project (and dist is a subdirectory of it).

Solution1: Remove symlink and then copy dist folder into node_modules. Solution2: Delete node_modules from library project. Solution3: Build library into dist folder that is not inside library project.

So it seems the difference was in how npm install is implemented and changed from npm v4 to v5 and how Node discovers relevant node_modules folders. Previously, npm install would copy a local shared libraries dist folder into the consuming project’s node_modules. Now it instead creates a symlink inside the consuming project’s node_modules.

So previously with a copied shared library dist folder, Node would run and crawl up the tree looking for node_modules, which it found immediately because that subfolder was already the consuming project’s node_modules. Now, when Node runs and crawls up the tree from the symlink, it discovers the shared library’s node_module folder from within that shared library project folder. (It’s being a little too smart knowing where the symlink points rather than where the symlink is defined.)

My solution was to change where my shared libraries generate their dist folders. They now generate the dist folder outside of their own project folder, beyond the reach of their own node_modules. I now reference that external dist folder when using the npm link command and npm install references the file:// target of the link command. Now when Node run the Angular application, it won’t get confused by finding these irrelevant node_modules folders.

To be fair, I like that they use symlinks instead of copying into node_modules because this allows quicker local development of a shared library without having to reinstall it every time you want to test a change. So I don’t think it’s a problem; we just need to understand how it works and work with it!

Well, that worked! Thanks a lot, @kukjevov

So, just to summarize in case someone else needs it.

In my common library I used this in my package.json

 "dependencies": {
    "@angular/core": ">=2.0.0",
    "@angular/common": ">=2.0.0",
    "@angular/router": ">=3.0.0",
    "@angular/http": ">=2.0.0",
    "@angular/platform-browser": ">=2.0.0",

I did this in a different branch, feature/angular4 and run yarn install When I checked my yarn.lock I saw this was inside:

"@angular/common@>2.0.0":
  version "4.0.1"
  resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.0.1.tgz#df488eada842b2d841ded750712292b18387b5b0"

Looks promising; if I’m not wrong it took the last available version for @angular/common, which is 4.0.1

Now I push the branch to my github repo and change to my app project.

I run yarn upgrade my_guthub_repo/common#feature/angular4 I check my yarn.lock and I have this

"@angular/common@4.0.0", "@angular/common@>2.0.0":
  version "4.0.0"
  resolved "https://registry.npmjs.org/@angular/common/-/common-4.0.0.tgz#ca18983222fdab4ecaa7a8b99eda6ff661e6dc92"

I run it, and it works 👍

I ran into this using angular-cli and after quite a bit of digging found that it had to do with the generated polyfills.ts. In it, it imports the core-js versions of reflect:

import 'core-js/es6/reflect';
import 'core-js/es7/reflect';

I commented those out and imported reflect-metadata:

import 'reflect-metadata';

Things started working just fine after. Not exactly sure why this works… my understanding was that core-js simply included the reflect-metadata polyfill…

Got the same error with angular v7 with an in-project library created with angular-cli. The cause in my case was that the components and modules were exported in public_api.ts via intermediate index.ts files. Removing index.ts files and exporting everything directly in public_api.ts solved this.

Pretty sure there is a good technical explanation for this, but from the perspective of a simple “user” this belongs to the category of “insane”!

but I’d need to confirm first that I can import a repo generated with Angular 2 from another project in Angular 4

yes, it should work without any issue.

is MyCommonModule your own or 3rd party module?

@Jayawardhana This is not a support group. Please post your question on Stack Overflow. And it does make sense, you do not declare a module in a module, you import it.

Delete node_modules page and re Download

None of the above solutions worked for me, I still get this error:

Error: Unexpected value 't' imported by the module 't'. Please add a @NgModule annotation.  build.js:1:44466

I’ve tried everything mentioned in this issue to no avail. Using the latest Angular packages (5.0.1), no matter what I try, I keep getting the same error:

Unexpected value 'MyCustomModule' imported by the module 'AppModule'. Please add a @NgModule annotation.
  • There is no internal node_modules inside node_modules/my-custom-module
  • All @angular/* dependencies are specified as peerDependencies
  • Tried different configuration settings in the custom library’s tsconfig.json. Tried skipTemplateCodegen both true and false (because of @robwormald comment above)

This was all working fine before.

I work with my team on a complex project developed in Angular : https://github.com/Alfresco/alfresco-ng2-components.

our project is structured in this way:

  • angular-cli-demo-app // demo app which we use to test our components
  • ng2-components
    • alfresco-angular-component-1 // component library based on Angular
    • alfresco-angular-component-2
    • alfresco-angular-component-3

Inside the “angular-cli-demo-app” we refer all our alfresco-angular-component using the tsconfig.json path:

"compilerOptions" :{
   ... 
 "path"{
      "alfresco-angular-component-1": [
        "../../ng2-components/alfresco-angular-component-1"
      ],
      "alfresco-angular-component-2": [
        "../../ng2-components/alfresco-angular-component-3"
      ],
      "alfresco-angular-component-3": [
        "../../ng2-components/alfresco-angular-component-3"
      ]
  }
}

Until we didn’t use the path reference strategy everything worked fine.

The way to fix this problem for us was to delete all the @angular folder inside the node_modules in all our components and all the shared folder

Why I think we were having this error: Even if we referred @angular it in the path tsconfig.json like this:

    "paths": {
      "rxjs/*": [
        "../node_modules/rxjs/*"
      ],
      "@angular/*": [
        "../node_modules/@angular/*"
      ]
    }

for some reason our component where still following the npm closer parent node_modules folder rule to get the @angular library which was resulting in having multiple @angular running in the project with multiple @NgModule and from there I suppose the error: Please add a @NgModule annotation

I hope this explanation save some debug time to the others, and also our project offers some reference to who wants to build a project + components library.

I was having this error which turned out to be as @Lavaei suggested. I was doing local development on my shared module in a different project, and used yarn link to use the local copy. I had run yarn install in the linked copy, to make development easier (intellisense in VS Code, etc.)

As soon as I deleted node_modules from the local shared project, this error went away. I’m also using Angular CLI.

Is it possible to tell Angular CLI to ignore these node_modules in my local copy of the shared repo? It would be nice to be able to both serve this shared repo directly (I have a “shell app” that displays some of the common components) as well as use it from a different repo with yarn link.

Same issue here. Had a library written in 4.4.4. After updating to 5.0.x, the only change I made was tweak the build process to use the new function signature of ngc, and then this error started popping up. I’ve check out the metadata file that I’m generating and it looks pretty fine to me:

{
  "__symbolic": "module",
  "version": 4,
  "metadata": {
    "YahteeDatePickerModule": {
      "__symbolic": "class",
      "decorators": [
        {
          "__symbolic": "call",
          "expression": {
            "__symbolic": "reference",
            "module": "@angular/core",
            "name": "NgModule"
          },
          "arguments": [
            {
              "imports": [
                {
                  "__symbolic": "reference",
                  "module": "@angular/common",
                  "name": "CommonModule"
                }
              ],

I am consuming the library via npm repo (no links involved, like a few comments above pointed out). It was all working fine when the lib was built using 4.x and consumed via 5.x. Now when the lib is built wit 5.x and used via 5.x, it breaks runtime with the following error.

ERROR Error: Uncaught (in promise): Error: Unexpected value 'YahteeDatePickerModule' imported by the module 'DatePickerModule'. Please add a @NgModule annotation.
Error: Unexpected value 'YahteeDatePickerModule' imported by the module 'DatePickerModule'. Please add a @NgModule annotation.

The consuming project is using CLI 1.5.

Maybe you have “node_modules” directory in your sub directories!

Any component written for 2.x should work for 4.x.

It’s important that you do not generate the factories in your library code. Your library code should only emit the metadata.json files.

Each application should then import NgModules from the shared library code, and compile each application as a unit.

This is baked into the entire design of angular’s compiler - backwards compatibility. This works because the metadata.json is backwards compatible, and ngFactory code can be generated for each version when an app is compiled.

It’s my own module. It contains some common components used by different projects. I wanted to upgrade one of those projects to Angular 4 but without touching the commons one.

@etwillbefine Checking in to confirm I have the same problem as described, however if I reinstall (npm install) for the library, the error returns.

I’m in a development environment where I use npm link in my library’s dist path (i.e., where build artifacts are placed), and then at the application run npm link my_library. Previously this worked fine, but my ModuleWithProviders configuration broke from angular-cli 1.0.1 to 1.1.3. So I fixed that error so that 1.1.3 seems to be fine, but now I get this error.

For what it’s worth, the linked library’s dist directory does not have a node_modules path; it’s outside the tree. It’s unclear to me how to work around this new problem just to restore the simplicity of using npm link.

I can´t create a plunkr with this setup nor upload this to my git account as it’s not open source code. I could try to create another 2 simple repos to reproduce this same scenario, but I’d need to confirm first that I can import a repo generated with Angular 2 from another project in Angular 4. That should not be an issue, right? Thanks!

@benelliott yep, I’ve been waiting for a solution for months now and this kind of stuff is a blocker to working with Angular. While I love promoting Angular for larger web dev teams because at its core it is a good framework, all these infrastructure issues and all the work that the Angular team has taken on is leading to lots of time wasted debugging issues like this.

What I ultimately did for my CLI app build was to start adding additional scripts for build and start when doing development against my libraries:

"build:dev": "npm run build -- --preserve-symlinks",
"start:dev": "npm run start -- --preserve-symlinks"

That gets around the problem without having to do exotic things like build my dist directory outside of the library’s source tree (and then link it from there).

I’m using the generator-angular2-library to create my libraries, which works great if anyone is interested (I’m not affiliated with their work at all other than my PR to add auto version migration to the dist/package.json on npm version ...).

Never mind. My issue was related to the DLLReferencePlugin in Webpack. I had to clean my dll directory and rebuild them.

It’s not negative, it’s a fact. Hijacking an issue with a “fix this code please” only creates noise for everyone. I’ve not only pointed the user in the right direction (StackOverflow), I’ve actually given a strong hint towards the solution:

you do not declare a module in a module, you import it

So there’s nothing negative about it and there’s for sure a few things helpful there.

Unhelpful and negative.

@linktothapast Unfortunately this is a very sneaky error that can be caused by different reasons. The last time I experienced this when I was adding a module to the root module and it had BrowserModule and BrowserAnimationsModule imported in it and this was my mistake. At least be sure that two above mentioned modules imported only once and only in the root module, otherwise you can have errors that are not very descriptive. Use CommonModule in your other modules instead of BrowserModule. In my case I had the same error as you and it was about the module that was totally fine. I hope it might be helpful. Also please check your imports, declarations, exports that everything on its place. I mean there is not a case that you declared a module in declarations or imported service etc. These kinds of mistake might cause weird errors as well.

I was searching all over for tips on this error. Turns out I forgot to add “typings”:“index.d.ts” to my package.json file

hi @davidanaya well if you use >=2.4.3 your library might compile with latest angular, but if you use this library that has dependency spefified this way it should work with any version of angular higher than 2.4.3. That means if your application has dependency "@angular/core": "2.4.5" your library should not create its own node_modules with different angular version since it is compatible with version specified in application package.json. Also if your application uses version 4.0.1 it is still in range of >=2.4.3 and it should be fine.

I am not completely sure, but i think this should work as far as your code will be backward compatible. It does not matter if your library is compiled with 2.4.3, or 4.0.1 if code compiles and works with both of them.

Got the same error with angular v7 with an in-project library created with angular-cli. The cause in my case was that the components and modules were exported in public_api.ts via intermediate index.ts files. Removing index.ts files and exporting everything directly in public_api.ts solved this.

Thanks! Specifying index.ts explicitly in public_api.ts (i.e., export * from './some-module/index') also works.

i used flash-message new version then i have this error in browser

[WDS] Disconnected! vendor.bundle.js:67956:10 Error: Unexpected module ‘FlashMessageModule’ declared by the module ‘AppModule’ zone.js:992

This is app.module.ts

// Required Fields if(!this.validateService.validateRegister(user)){ this.flashMessage.warning(‘Please fill in all fields’, {cssClass:‘alert-danger’, timeout:3000}); return false; }

// Validate Email
if(!this.validateService.validateEmail(user.email)){
  this.flashMessage.warning('Please use a valid email', {cssClass:'alert-danger', timeout:3000});
  return false;
}

I am also facing same issue

Uncaught Error: Unexpected value ‘Http’ imported by the module ‘AppModule’. Please add a @NgModule annotation. at syntaxError (compiler.js:215) at compiler.js:10468 at Array.forEach (<anonymous>) at CompileMetadataResolver.push…/node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNgModuleMetadata (compiler.js:10443) at JitCompiler.push…/node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._loadModules (compiler.js:22567) at JitCompiler.push…/node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:22548) at JitCompiler.push…/node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync (compiler.js:22508) at CompilerImpl.push…/node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:143) at PlatformRef.push…/node_modules/@angular/core/fesm5/core.js.PlatformRef.bootstrapModule (core.js:4790) at Object…/src/main.ts (main.ts:11)

I also faced the same issue but resolved by updating the tsconfig.app.json with following code:

{ “extends”: “…/tsconfig.json”, “compilerOptions”: { “outDir”: “…/out-tsc/app”, “module”: “es2015”, “baseUrl”: “”, “types”: [], “typeRoots”: [ “node_modules/@types” ], “lib”: [ “es2017”, “dom” ], “paths”: { “@angular/": [ "…/node_modules/@angular/” ] } }, “exclude”: [ “test.ts”, “**/*.spec.ts” ] }

Its worked for me try it from your end.

This kind of error can also occur during the tests, when in your imports: […] declaration you declare “SomethingComponent” instead of “SomethingModule”.

Just to add - when I delete a few components I finish with a problem described here. In both cases I use Angular cli.

i am getting this error how do i fix this, i am new to angular

Error: Unexpected value ‘Http’ imported by the module ‘AppModule’. Please add a @NgModule annotation. vendor.js:78125:34 syntaxError http://localhost:8100/build/vendor.js:78125:34 CompileMetadataResolver.prototype.getNgModuleMetadata/< http://localhost:8100/build/vendor.js:91973:44 forEach self-hosted:267:13 CompileMetadataResolver.prototype.getNgModuleMetadata http://localhost:8100/build/vendor.js:91956:13 JitCompiler.prototype._loadModules http://localhost:8100/build/vendor.js:103389:47 JitCompiler.prototype.compileModuleAndComponents http://localhost:8100/build/vendor.js:103362:31 JitCompiler.prototype.compileModuleAsync http://localhost:8100/build/vendor.js:103291:32 PlatformRef.prototype.bootstrapModuleWithZone http://localhost:8100/build/vendor.js:4893:16 PlatformRef.prototype.bootstrapModule http://localhost:8100/build/vendor.js:4879:16 [196] http://localhost:8100/build/main.js:191:1 webpack_require http://localhost:8100/build/vendor.js:55:12 webpackJsonpCallback http://localhost:8100/build/vendor.js:26:23 <anonymous> http://localhost:8100/build/main.js:1:1

@omouse, sure:

Original AppModule definition:

import { SharedComponent } from './_shared/shared.component';

@NgModule({
    declarations: [SharedComponent]
})
export class AppModule { }

Updated AppModule

import { SharedComponent } from './_shared/shared.component';

@NgModule({
    exports: [SharedComponent]
})
export class AppModule { }

LocalModule

import { SharedComponent } from 'app/_shared/shared.component';

@NgModule({
    declarations: [SharedComponent]
    exports: [SharedComponent]
})
export class LocalModule { }

Thanks @kukjevov so it really is a problem if my library uses Angular 2 and my app uses Angular 4. The thing is my library in Angular 2 is used by other applications which are in Angular 2 and I can´t migrate them at the moment, so it has to stay in Angular 2.

If I use >=2.4.3 in my library does it mean that it will use Angular 4 when I build my app and Angular 2.4.3 when I use it with my other apps?

@Toxicable thanks for your input, I think that’s exactly what’s happening.

Had the same problem - turned out the ng-pdf-make project had a subdirectory of node_modules with its own angular version which caused the bug. After deleting the local node_modules it worked!

This is a closed ticket; not sure the devs look at replies to closed tickets. Maybe time to open a new ticket?

Also, I wanted to point out that, at least for me, I found and mirrored setting up my modules as demonstrated in the ngx-rocket/starter-kit and it has worked well ever since. The only gotcha is when my IDE decides to use the shortcut notation (e.g., @shared/whatever) inside of a module when it shouldn’t.

Similar to @linktothapast I have tried everything I can think of. I’ve created 2 simple angular 5 projects, one to package up, and one to consume. I use npm link to connect them, and I’ve put the files in a Plunkr for the packaged file to see if anybody knows what I’m doing wrong. Can’t think of any other way but rolling back and waiting a few more weeks until smarter people than me run into the problem and post a fix 😃. The projects themselves build and run fine, it’s only when exporting for library usage.

https://plnkr.co/edit/bOzJh5ncDSBKGoHggfDI?p=info

Is there an issue open that has the aim to fix this issue, in this project or another? @magemello has a good workaround, but I find myself having to delete my node_modules often when making changes/adding new dependencies in my components library. Why aren’t the paths in tsconfig.json being respected?

Actually, I have fixed the issues and was able to run my library in new project. part of the fix was two things: 1- remove the line: import “reflect-metadata”; from common.ts file Common library. 2- using export class with static function like ForRoot() to return ModuleWithProviders for NgModule instead of just exporting normal class, not sure why the first point caused that error, and it took me two days to isolate my code line by line to find once that caused that issue and fix it,

To all these people telling u to “remove the node modules folder in the lib”, that will completely remove the ability to develop the lib and test what you’re doing at the same time… Since you need the lib’s deps installed in order to build etc.

I got this error if I import “reflect-metadata”; again this will clear the Metadata cache and Angular will not be able to find the ngModule decorator appropriately.

I removed my import 'reflect-metadata'; and used window['Reflect'].getMetadata() in my script.

Slightly the same, but mostly different:

To give my two cents, I am using Angular 4.3.5, and I have a component in my main app module that I wanted to use in a local (non-npm) module. I had mistakenly added it to my local module’s ngModule’s import definition, which gave me this error:

Uncaught Error: Unexpected directive 'SharedComponent' imported by the module 'LocalModule'. Please add a @NgModule annotation.

Once I refactored my @ngModule definition, so that my SharedComponent was in both the declarations AND the exports, it worked like a charm.

HTH

I can confirm the findings: deleting node_modules from the shared library works. What’s strange is that I did NOT change the version of angular or angular-cli but rather upgraded my Node.js installation. So there’s some new relationship with probably tsconfig moduleResolution and that combinations of newer Node + angular-cli installs lock the shared library node_modules directory and makes the run time confused. For now, I can automate deleting or hiding those local node_modules directories but it’s a real PITA.

Can confirm @irontoby I had the same issue and after removing node_modules and reinstall the error was gone. Using angular-cli as well. It happen for me after upgrading from 4.1.0 to 4.2.0-rc.0

Are you guys saying that any 3rd party library that has “@angular/core”:“^2.0.0” (as an example) in it’s package.json won’t work when imported as a module? This is a nightmare, none of my 3rd party libraries work if this is the case.