Beta 6, AoT possible issue?
spock123 opened this issue · 24 comments
Hi there,
I'm playing with Beta6 and AoT compilation.
I'm not sure what the problem is, but AoT throws an error as soon as I add the NgReduxModule.forRoot() method.
Only code I have in my app is that line.. and the AoE throws the following error:
Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function
Any ideas, guys?
I'm not doing anything other than importing the module - I*m not even configuring it.. doing step by step to make sure which line creates the error.
I also found this issue.
Can confirm, same problem here.
Coming from a working AOT build with 4.0.0-aotbeta.3
If you are not using an @select
decorator - you should be able to. Currently the decorators don't play well with AoT, and still looking for a solution, but may just be a limitation of the compiler.
If you have a component / app that is throwing an error that is't using @select
can you point me to an example?
The potential bug ist visible in our company starter project:
https://bitbucket.org/DcsMarcRemolt/dcs-angular2-starter/branch/ng2-redux-issue-234
The master ist still on aotbeta.3 and works, the branch I linked above is on beta.6 and there I get the error. The only difference is the package version and the necessary code changes (.forRoot()).
The project does not yet use a select decorator, as this is our empty starting point for coding a2 apps.
Tested with:
- node 6.9.1
- npm 3.10.8
- package versions are hardcoded (no ^ or ~)
Steps to reproduce:
- git checkout master
- npm install
- npm run ngc
Works
- git checkout ng2-redux-issue-234
- npm install
- npm run ngc
Breaks with mentioned error
As @DcsMarcRemolt says, it doesn't take much to replicate it.
You don't have to create a store, you don't have to configure a store.
It's enough to import the Ng2ReduxModule and call the .forRoot() method.
Thanks for providing a test repo. Let me take a look.
@e-schultz I can reproduce the issue with @DcsMarcRemolt's repo. The NgReduxModule.forRoot()
is indeed what's triggering it; commenting out that line makes the error go away.
I think the forRoot
function itself needs to be explicitly exported?
Anyway all, we have a few issues related to AoT right now. AoT brings a lot of (presently undocumented) limitations to what TypeScript constructs you can use as exports from your NgModules
and this has blindsided us a bit.
Rest assured this is high on the priority list. For now I suggest working in JIT mode instead until we get things sorted out.
Think I found the source of the issue, and I'll try and get a fix out tonight. Basically
- index.metadata.json was not being generated
This is because I was doing
@NgModule({})
class MyModule { }
export {
MyModule,
OtherStuff }
when exporting like that, the metadata doesn't seem to get generated.
Changing it to:
@NgModule({})
export class MyModule { }
export {
OtherStuff
}
then the metadata gets generated properly.
I will try and get a fix/publish out for this later today
@spock123 just published 4.0.0-beta.7 and tried running your starter repo with it (build:prod / serve:prod) - and was able to get it running w/o spitting up errors.
Let me know if it's working for you - thanks for your patience.
@e-schultz Thank you so much for your effort, it's super appreciated.
So a bit of progress:
- the compiler now runs without throwing any errors.
- however, when webpack tries to build, it does build but throws this error:
ERROR in [default] /Users/spock/projects/angular2-webpack2-typescript2/compiled/src/frontend/app/app.module.ngfactory.ts:175:14
Generic type 'NgRedux<RootState>' requires 1 type argument(s).
Is it something I did wrong?
Btw I updated my starter repo. Replication:
// Install dependencies
npm install
// Compile
npm run aot
// Compile and build
npm run build-aot
@DcsMarcRemolt I verified ng2-redux@4.0.0-beta.7 with your repo and it appears to be working now. Btw, you should also update to rxjs@5.0.0-beta.12 to resolve some npm peer dependency warnings.
@spock123 I'm assuming you're talking about a different starter repo? Is it something you can share so I can take a look?
I'm sorry, here it is:
One thing I have noticed when using generics in a constructor - first run of ngc is fine, but if you leave the .ngfactory.ts artifacts around and run ngc again - then it complains with that error.
try removing the ngfactory files and running the build - and does it work?
then try running it again - that is when the error happens (at least for me)
Unfortunately that didn't change anything for me, sorry.
@e-schultz so I now managed to get it to work by providing the workaround @NeoLSN used, by extending NgRedux, and "provide" that new class instead of NgRedux (see @#228)
@spock123 when injecting NgRedux into your components/services, does
export class SomeClass {
constructor(ngRedux: NgRedux <any> ) {}
}
work? might be simpler than needing to create a wrapper-work around that accomplishes the same.
I have a feeling this might be a limitation of AoT, but has me wondering if you could then do ... (thinking out loud, will try and experiment tonight)
export class SomeClass {
private _store: NgRedux <AppState> ;
constructor(ngRedux: NgRedux <any> ) {
this._store = ngRedux as NgRedux<AppState>
}
ngOnInit() {
this.stuff = this._store.select( /* back to getting a strongly typed store */ )
}
}
Not ideal, but if AoT is having issues with injecting generics as parameters - might be a limitation we need to deal with until the compiler is updated to accommodate it.
There is issue #12262 on the angular issue tracker talking a bit about this.
@e-schultz
I just tested and it works! Both @select and injecting the store and using store.select()
My setup:
Webpack: 2.1.0-beta.22
Node: 6.3.0
Angular: 2.1.1
Ng2Redux: 4.0.0-beta.7
Repo:
https://github.com/spock123/angular2-webpack2-typescript2
Extend NgRedux:
import { Injectable } from '@angular/core';
import { NgRedux } from 'ng2-redux';
@Injectable()
export class _NgRedux extends NgRedux<any> {
constructor(){
super();
}
}
Import this extended class in the app module:
import { _NgRedux } from './store/extended-class';
import { NgRedux } from 'ng2-redux';
In the app module, use provide() so all references to NgRedux will now get this extended class instead:
let providers = [
{ provide: NgRedux, useClass: _NgRedux },
... other providers in your app
];
....
@NgModule({
imports: [
NgReduxModule.forRoot(),
other modules....
],
declarations: [
bla bla bal
],
providers: providers,
bootstrap: [ AppComponent ]
})
export class AppModule{
// Initialize redux store in the constructor
}
Compile, build and serve the app: (localhost: 8080)
npm install && npm run build-aot && npm run serve:dist
PS: the build generates Serviceworker also, so make sure to remove it in chrome devtools (under application) after...
I just import the store as usual in my components:
import { NgRedux, IAppState, select } from 'my-store-bundle';
import { Observable } from 'rxjs/Observable';
export class SomeClass {
@select('whatever') whatever$: Observable<any>;
constructor(ngRedux: NgRedux <IAppState> ) {}
ngOnInit() {
// Nothing to see here..
// Not using the injected store, but we could use this.ngRedux.select() here
}
}
@SethDavenport
Oh, I see.
I think this issue can be closed now