angular/angular-cli

Error loading npm linked custom library with aot

Manest opened this issue Β· 31 comments

Please provide us with the following information:

OS?

Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)

Mac OSX, El Capitan

Versions.

Please run ng --version. If there's nothing outputted, please run in a Terminal: node --version and paste the result here:

angular-cli: 1.0.0-beta.24
node: 6.9.2
os: darwin x64
@angular/common: 2.4.1
@angular/compiler: 2.4.1
@angular/core: 2.4.1
@angular/forms: 2.4.1
@angular/http: 2.4.1
@angular/platform-browser: 2.4.1
@angular/platform-browser-dynamic: 2.4.1
@angular/router: 3.4.1
@angular/compiler-cli: 2.4.1

Repro steps.

Was this an app that wasn't created using the CLI? What change did you do on your code? etc.

From a really fresh angular cli project.

Only adding in app.module.ts :

import { MessageModule } from 'my_lib';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule, 
    MessageModule.forRoot() // <-- include here
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Adding one of the component in app.component.html
<my-message type="error">This is an error message</my-message>

And running
ng build --aot

The log given by the failure.

Normally this include a stack trace and some more information.

chunk    {0} main.bundle.js, main.bundle.map (main) 1.48 kB {2} [initial] [rendered]
chunk    {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 1.77 kB {3} [initial] [rendered]
chunk    {2} vendor.bundle.js, vendor.bundle.map (vendor) 1.06 MB [initial] [rendered]
chunk    {3} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]

ERROR in Error encountered resolving symbol values statically. Calling function 'makeDecorator', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol Injectable in /Users/admin/dev/web-library/node_modules/@angular/core/src/di/metadata.d.ts, resolving symbol OpaqueToken in /Users/admin/dev/web-library/node_modules/@angular/core/src/di/opaque_token.d.ts, resolving symbol OpaqueToken in /Users/admin/dev/web-library/node_modules/@angular/core/src/di/opaque_token.d.ts

ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in '/Users/admin/dev/web-library/ng24/src'
 @ ./src/main.ts 4:0-74
 @ multi main

ERROR in ./~/@angular/core/src/linker/system_js_ng_module_factory_loader.js
Module not found: Error: Can't resolve '/Users/admin/dev/web-library/ng24/src/$$_gendir' in '/Users/admin/dev/web-library/ng24/node_modules/@angular/core/src/linker'
 @ ./~/@angular/core/src/linker/system_js_ng_module_factory_loader.js 69:15-36 85:15-102
 @ ./~/@angular/core/src/linker.js
 @ ./~/@angular/core/src/core.js
 @ ./~/@angular/core/index.js
 @ ./src/main.ts
 @ multi main

Mention any other details that might be useful.

My message module declare and exports the message component, with inlined css/html.

It's Exported with a forRoot :

export class MessageModule {
  public static forRoot(): ModuleWithProviders {
    return {ngModule: MessageModule, providers: []};
  }
}

my_lib is generated with ngc, with a .metadata.json near each d.ts.
With following tsconfig parameters :

...
    "target": "es5",
    "module": "es2015",
...
  "angularCompilerOptions": {
    "skipTemplateCodegen": true
  }

Thanks! We'll be in touch soon.

Having a very similar issue here with a similar setup. I'd love to see someone respond to this.

Calling function 'makeDecorator', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function

Where is this makeDecorator function? is it a part of your project?

I had a similar problem and it was caused by a small project which I imported and didn't appear to be prepared for aot yet. The makeDecorator function wasn't part of the project code either.

I have the same problem getting this error. This error is thrown when I try to import a module coming outside my angular-cli root.
E.g. import {TestModule} from '../../../../../../Private/test-share/src/app/test/test.module';

Doesn't matter if I use the source .ts file or the compiled version. Also happens when linking with yarn link.

As far as I can tell now, there is definitely a problem with imported modules outside the projects root. When I use yarn link, which creates a symlink, and try to import the module in my project, I get the "Calling function 'makeDecorator'" error. Now if I drag my library into another npm module (e.g. @angular/common) everything works just fine.

This means it is not possible to use self-written libs with angular-cli currently, unless they are already published somewhere. Hope this gets fixed soon.

@SebastianSchenk check this one as an example, I had the same issue but this example seems currently working fine.

npm install https://github.com/msusur/angular-lib-exp.git --save
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AngularLibExpModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
<h1>
  {{title}}:
  {{ 3.23 | roundDown }}

  <cm-display [message]="title"></cm-display>

</h1>

@msusur thank your for the example. Using .forRoot helps as a workaround to avoid the error.
However, it also helped me to find the root of the problem. I just cloned the lib from github and linked it with yarn link to my project. After that, I imported the module and added it to the imports array of my AppModule without using .forRoot. Everything worked, no errors. After installing the dependencies of the lib, the error was thrown. Now I had to use .forRoot to make to error disappear.

To sum it up. The error occurs only when the lib also contains node_modules. I think it has something to do with @angular/* being a in both node_modules.

@SebastianSchenk I was having a very similar issue with a feature module I am building under it's own dependency. With you're hypothesis, I removed my node_modules directory from my feature module before linking it. After that, everything worked like a charm.

I'm getting a bunch of errors in my feature module since none of it's dependencies are present... but that more or less add to an issue with duplication in the node_modules folder.

@jppellerin I had the same issue, removing node_modules from the feature module fixed it. Thanks for sharing! πŸ‘

It seems like this is a issue caused by Typescript and not by Angular CLI. Typescript has problems resolving dependencies when yarn link or npm link is used, as you can see here #11916 and here #6496. This problem could be solved with Typescript 2.1 (read more here).

For now, thanks to this post #1858 I found a good workaround, which doesn't affect the actual code of the library, as it is the case with an empty .forRoot(). Furthermore, you don't have to delete node_modules anymore. Just add a paths property with all angular dependencies to the tsconfig file of the Angular CLI project, where you include your library with yarn link or npm link.

Here is my full tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es6", "dom"],
    "mapRoot": "./",
    "module": "es6",
    "moduleResolution": "node",
    "outDir": "../dist/out-tsc",
    "sourceMap": true,
    "target": "es5",
    "typeRoots": [
      "../node_modules/@types"
    ],
    "paths": {
      "@angular/common": ["../node_modules/@angular/common"],
      "@angular/compiler": ["../node_modules/@angular/compiler"],
      "@angular/core": ["../node_modules/@angular/core"],
      "@angular/forms": ["../node_modules/@angular/forms"],
      "@angular/platform-browser": ["../node_modules/@angular/platform-browser"],
      "@angular/platform-browser-dynamic": ["../node_modules/@angular/platform-browser-dynamic"],
      "@angular/router": ["../node_modules/@angular/router"],
      "@angular/http": ["../node_modules/@angular/http"]
    }
  }
}

Closing as it has been answered. Great writeup and workaround by @SebastianSchenk !

I edited the title and added the FAQ label to make it easier for people having the same problem to find this.

@SebastianSchenk perhaps worth noting: Your solution (which resolved this issue for me - a million thanks) can be rewritten as:

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

Hi,

Anybody is albe to explain what is the real cause? I have added that path mapping and it resolves my problem. But I think this is not really a solution as more workaround.

When I create new project using ng new XXXX, simulate identical setup All is fine and I dont have a issue.
just for my existing project.

I wasn't able to resolve it via @SebastianSchenk 's workaround. I have the following error:

Error encountered resolving symbol values statically. Calling function 'makeParamDecorator', function calls are not supported.

I'm using Angular 4.1.3 with Angular-CLI 1.0.2 and Ionic 3.4.2. The error shows up when I try to run the following command:

ionic cordova build android --prod --release

The workaround does not work here. As soon as i add the

import { localStorageSync } from 'ngrx-store-localstorage';

AND

StoreModule.forRoot(
      reducers, {
        metaReducers: [
          localStorageSync({
            keys: ['auth', 'customer']})
        ]
      }
    ),
```

It fails with the error above. Adding the modules to tsconfig does not solve the problem. As soon as i save the project it compiles successfully.

This paths: { "@angular/": ["../node_modules/@angular/"] } workaround didn't work for me. Please help :(

Building with aot, using npm link. I have included paths as above. However this does not work.
If I remove the node_modules dir from the linked library then this does solv the issue.

The error I get (at runtime) is:

compiler.es5.js:1690 Uncaught Error: Unexpected value 'DataTableModule' imported by the module 'MyModule'. Please add a @NgModule annotation.

Looks like this is an open issue with angular-cli

Workaround with paths variable have not helped me as well. I am trying to create a factory for my @ngrx reducers

export const reducers = {
  tips: collectionReducer('tips'),
  games: collectionReducer('games'),
  eventTypes: collectionReducer('eventTypes'),
}

ERROR in Error: Error encountered resolving symbol values statically. Calling function 'collectionReducer', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol gamesReducer in .....

I've encountered this error when having a dependency installed from the local file directory. NPM5 creates a symlink which doesn't seem to want to play nice with the AOT compiler. I solved it by downgrading to NPM3 with npm install -g npm@3 which will by default install the dependency simulating an install from NPM, and use the package.json and .npmignore files. Alternatively, you may want to try something like the npm package npm install-local https://www.npmjs.com/package/install-local.

Hopefully, this helps someone else down the road.

It looks like npm@5 intentionally broke this: npm/npm#15900

@Polyergic So what would be the fix now? I'm struggling...

@chrillewoodz, for the time being I'm both avoiding file: deps and avoiding AOT, and hoping at least AOT is fixed before I need the performance. Our internal deps are on our private github, which npm seems to handle correctly, it just makes some debugging tedious. If you need AOT now, AFAIK you can either just copy them into your tree or try to make them appear as git submodules.

just a note, this "paths" needs to be added to your tsconfig.json on your app , not your library folder, in case you are building a custom module.

SebastianSchenk answer works for me.

rtm commented

SebastianSchenk's answer does not work for me unfortunately. I am on v6.0.0 of everything. The error I am getting is

ERROR in ../@nims/ngutils/lib/collapsible-fieldset/collapsible-fieldset.component.ts(13,2): Error during template compile of 'CollapsibleFieldsetComponent'
Function calls are not supported in decorators but 'Ι΅makeDecorator' was called in 'Component'
'Component' calls 'Ι΅makeDecorator'.

I am not using npm link per se, but lerna, which internally I think does pretty much the same thing. This error occurs even with the --preserve-symlinks option to ng build, which at one point was suggested as a solution (#7097).

The component that it is complaining about is very simple. It just has a couple of @Input() properties and a short template. Looking at the component.js or component.metadata.json reveals nothing obvious.

@rtm
Can you create a minimal repro of your issue?

rtm commented

@alexzuza Thanks for following up, but this problem magically solved itself, no idea how.

So maybe it's a VS Code thing or npm thing, I don't know, but somehow the file paths to our symlink'ed modules had their direct paths added (../../../patient/node_modules/*). We spent quite awhile trying to hunt down this issue, and apparently an automated process re-wrote the file paths in app.module.ts.

SHOULD BE:

import { BrowserModule } 		from '@angular/platform-browser';
import { NgModule } 			from '@angular/core';
import { RouterModule, Routes } 	from '@angular/router';
import { HttpClientModule } 		from '@angular/common/http';
import { BrowserAnimationsModule }	from '@angular/platform-browser/animations';
import { FlexLayoutModule } 		from '@angular/flex-layout';
import { FormsModule }			from '@angular/forms';

OVERWRITTEN FILE PATHS:

import { BrowserModule } 		from '../../../patient/node_modules/@angular/platform-browser';
import { NgModule } 			from '../../../patient/node_modules/@angular/core';
import { RouterModule, Routes } 	from '../../../patient/node_modules/@angular/router';
import { HttpClientModule } 		from '../../../patient/node_modules/@angular/common/http';
import { BrowserAnimationsModule }	from '../../../patient/node_modules/@angular/platform-browser/animations';
import { FlexLayoutModule } 		from '../../../patient/node_modules/@angular/flex-layout';
import { FormsModule }			from '../../../patient/node_modules/@angular/forms';

For my case it is

"@angular/*": ["./node_modules/@angular/*"]

instead of

"@angular/*": ["../node_modules/@angular/*"]

in tsconfig.json. Then it works. πŸ’―

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.