ngx-translate / core

The internationalization (i18n) library for Angular
MIT License
4.48k stars 570 forks source link

AoT compilation fails without config #281

Open timfogarty1549 opened 7 years ago

timfogarty1549 commented 7 years ago

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.

ocombe commented 7 years ago

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 ?

SamVerschueren commented 7 years ago

Could you share your SystemJS config?

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

timfogarty1549 commented 7 years ago

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

SamVerschueren commented 7 years ago

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

import { TranslateService } from 'ng2-translate';
zackarychapple commented 7 years ago

@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

SamVerschueren commented 7 years ago

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.

zackarychapple commented 7 years ago

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]
    }),
SamVerschueren commented 7 years ago

Glad it got resolved.

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

Matmo10 commented 7 years ago

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

SamVerschueren commented 7 years ago

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

zackarychapple commented 7 years ago

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

Matmo10 commented 7 years ago

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()
SamVerschueren commented 7 years ago

Thanks for clarifying, will look into that.

stefannikolei commented 7 years ago

@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?

ocombe commented 7 years ago

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

KarolBuchta commented 7 years ago

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