Core: AoT compilation fails without config

Created on 18 Oct 2016  路  16Comments  路  Source: ngx-translate/core

While my app works great with JIT compiling, I have not been able to get AoT to work. The file appModule.ngfactory.js gets created, but then contains errors. The error is in the imports.

In appModule.ngfactory.js I see ng2-translate gets imported, such as

import * as import8 from 'ng2-translate/ng2-translate';

but then later on, it tries to import translate.service with a relative path.

import * as import189 from '../../src/translate.service';

which then gives the error

Error: Error at /workspace/project/app/appModule.ngfactory.ts:196:28: 
Cannot find module '../../src/translate.service'.

it seems to me that in AoT, the import of '../../src/translate.service'; shouldn't happen at all because the contents of that file was already imported with 'ng2-translate/ng2-translate'.

In my typescript code, I import TranslateModule through SharedModule, but in other classes, I inject TranslateService through the constructor so that I can programmatically access its methods. For example,

import {TranslateService} from 'ng2-translate/ng2-translate';
...
    constructor( private translate: TranslateService ) {}
...
    ngOnInit() {
        this.subscription = this._route.params
            .flatMap( (params,i) => {
                this.results = [];
                this.chart = params['chart'];
                return this._restService.getStatsChartData( this.chart );
            } )
            .map( (data) => {
                this.results = data;
            })
            .merge( this.translate.onLangChange )
            .flatMap( (data,i) => {
                return this.translate.get( "STATS."+this.chart.toUpperCase() );
            } )
            .subscribe( (values) => {
                this.translations = values;
            });
    }

Is this an error with the ng-translate package, perhaps the metadata.json ? or is it an error in the way I'm importing and injecting TranslateService into my classes? Again, the app works fine with JIT, but won't compile with AoT.

medium bug

Most helpful comment

Yes. Just to clarify, I had to use this for AOT to work:

export function createTranslateLoader(http: Http) {
   return new TranslateStaticLoader(http, './i18n', '.json');
}

...

  TranslateModule.forRoot({
      provide: TranslateLoader,
      useFactory: (createTranslateLoader),
      deps: [Http]
    }),

While just doing this would NOT work for AOT:

TranslateModule.forRoot()

All 16 comments

Hmm good point, I think this is a problem with the new feature from @SamVerschueren and my new build system. The new exported bundle is now index.js, but the ngc is built based on ng2-translate.ts
@SamVerschueren any idea ?

Could you share your SystemJS config?

@ocombe Haven't upgraded yet. Let me do that and I'll get back with my findings.

SystemJS is not used in AoT

here is my tsconfig-aot.js (while there is a tsconfig.js for JiT for development)

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  },

    "files": [
        "app/appModule.ts",
        "app/main-aot.ts",
        "./typings/index.d.ts"
    ],

    "angularCompilerOptions": {
        "genDir": "aot",
        "skipMetadataEmit" : true
    }
}

and in package.json

{
  "scripts": {
...
    "aot": "node_modules/.bin/ngc -p tsconfig-aot.json",
...
   }
}

here is main-aot.ts. (while main.ts is configured for JiT for development)

import { platformBrowser }    from '@angular/platform-browser';

import { AppModuleNgFactory } from '../aot/app/appModule.ngfactory';

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

all followling the angular.io AoT manual

https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

Change the import like this. More information on the changes could be read in this post.

import { TranslateService } from 'ng2-translate';

@SamVerschueren using the angular-cli i still have this issue on the latest version. i'm on 3.1.3 and tried doing the imports as import { TranslateService } from 'ng2-translate'; my import is the standard ngModule import of TranslateModule.forRoot(), @ocombe

I created a repository to test this. I never worked with angular-cli so I installed it, created a new project in the first commit and added ng2-translate in the second commit.

https://github.com/SamVerschueren/ng2-translate-aot-test

I ran the following command and all seem to work

$ ng serve --prod

I wasn't sure if this did AoT compilation and couldn't find docs for that, so I also ran it with

$ ng serve --prod --aot

I checked the sourcecode and the template was compiled so that worked correctly. So not sure where it goes wrong then.

So as per @SamVerschueren's documentation in the repo it is actually a requirement to use the following even if you are using the standard loader apparently. This did get it working for me. Thank you!

    TranslateModule.forRoot({
      provide: TranslateLoader,
      useFactory: (createTranslateLoader),
      deps: [Http]
    }),

Glad it got resolved.

@timfogarty1549 Could you check if it works for you with the changes suggested?

AOT doesn't work for me either without explicitly configuring the TranslateModule like @zackarychapple suggested. But it does work once I do that.

ERROR in ./src/compiled/src/app/app.module.ngfactory.ts
Module not found: Error: Can't resolve '../../../translate.service' in '/Users/me/ng2app/src/compiled/src/app'
 @ ./src/compiled/src/app/app.module.ngfactory.ts 77:15-52
 @ ./src/main.browser.aot.ts

ERROR in [default] /Users/me/ng2app/src/compiled/src/app/app.module.ngfactory.ts:78:26 
Cannot find module '../../../translate.service'.

ERROR in [default] /Users/me/ng2app/src/compiled/src/app/app.module.ngfactory.ts:342:93 
Property 'translateLoaderFactory' does not exist on type 'typeof "/Users/me/ng2app/src/app/app.module"'.

my main.browser.aot.ts is identical to https://github.com/qdouble/angular-webpack2-starter/blob/master/src/main.browser.aot.ts

@Matmo10 So you are just using TranslateModule.forRoot() without any config?

@SamVerschueren I was trying to use without the config as well.

Yes. Just to clarify, I had to use this for AOT to work:

export function createTranslateLoader(http: Http) {
   return new TranslateStaticLoader(http, './i18n', '.json');
}

...

  TranslateModule.forRoot({
      provide: TranslateLoader,
      useFactory: (createTranslateLoader),
      deps: [Http]
    }),

While just doing this would NOT work for AOT:

TranslateModule.forRoot()

Thanks for clarifying, will look into that.

@SamVerschueren i would suggest you to look into the Router from angular. They use forRoot too
export declare class RouterModule { static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders; }

And here you just use any. Perhaps changing this will help?

I think that this should be fixed in 6.0.0 but I'll have to check

I am using ngx-translate 7.00, having the same issue. I tried the workaround, and still get an error when compiling with ngc.

See here: #578

Was this page helpful?
0 / 5 - 0 ratings