Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Ahead-of-Time compiler: must I make all class properties public?

Tags:

Angular 2 rc 6, typescript 2, node 4.5.0, npm 2.15.9 on Windows 7

I'm trying to move from Just-in-Time to Ahead-of-Time compilation and I'm relying on these resources:

  • Angular 2 - Ahead-of-time compilation how to
  • https://github.com/angular/angular/tree/master/modules/@angular/compiler-cli#angular-template-compiler

I understand that I need to run the compiler ngc to generate ngfactory.ts files, and that I need to change main.ts to use platformBrowser instead of platformBrowserDynamic to bootstrap. I've hit a roadblock though and don't know how to proceed.

1. I've confirmed that the App runs without errors using Just-in-Time compilation. My main.ts is:

enableProdMode(); platformBrowserDynamic().bootstrapModule(AppModule); 

2. I clear all my app files from my production folder, but keep 3rd party libraries (eg: Angular 2, Angular 2 Material)

3. I run "node_modules/.bin/ngc" -p ./ This runs with no output to the console. I see an .ngfactory.ts file for each of my .ts components and modules. I also see a .css.shim.ts file for each of my .css that held component styles. In addition, .js and .js.map files have been transpiled and placed in the production directory

4. If I try to run the app at this point, I see 404 not found errors for all the .html files that held component templates

5. I manually move all template files (.html) to production dir and run the App. It runs fine, but it still uses Just-in-Time compilation (255 requests, including compiler.umd.js)

6. I change my main.ts to:

enableProdMode(); platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); 

On its own, this makes no difference since the new code has not been compiled. However, I don't know what to do from here.

Should I run ngc again? If so I get lots of errors of the type:

Error at C:/path/to/notify.component.ngfactory.ts:113:41: Property 'visible' is private and only accessible within class 'NotifyComponent' ... (many more like that with lots of properties from lots of components) Compilation failed 

Does using AoT compilation mean that I must make all my class properties public? Am I missing a step?

like image 885
BeetleJuice Avatar asked Sep 07 '16 20:09

BeetleJuice


People also ask

What is true with Angular ahead-of-time compiling?

The Angular ahead-of-time (AOT) compiler converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase before the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser.

What is difference between aot and JIT?

JIT downloads the compiler and compiles code exactly before Displaying in the browser. AOT has already complied with the code while building your application, so it doesn't have to compile at runtime. Loading in JIT is slower than the AOT because it needs to compile your application at runtime.

What is ahead-of-time compiler?

In computer science, ahead-of-time compilation (AOT compilation) is the act of compiling an (often) higher-level programming language into an (often) lower-level language before execution of a program, usually at build-time, to reduce the amount of work needed to be performed at run time.

What are the ways to control AOT compilation?

When you use the Angular AOT compiler, you can control your app compilation in two ways: By providing template compiler options in the tsconfig. json file. By specifying Angular metadata.


2 Answers

For a given component all its members (methods, properties) accessed by its template must be public in the ahead-of-time compilation scenario. This is due to the fact that a template is turned into a TS class. A generated class and a component are 2 separate classes now and you can't access private members cross-class.

In short: you can't access private members in your templates if you want to use ahead-of-time compilation.

like image 135
pkozlowski.opensource Avatar answered Sep 22 '22 02:09

pkozlowski.opensource


So is too, in Final release of Angular 2 whit Ionic2 RC1

A workaround for Fields could be to use getters without setters

protected _myField: any;  get myField(): any {    return this._myField;  } 

You can also see other JiT to AoT considerations to adapt your code in this blog of Isaac Mann

  1. const lambda => export function
  2. default export => named export
  3. private, protected accessors should be changed to public for any members accessed from template
  4. dynamic component template => static template
  5. moduleId should be set on components with templateUrl
like image 41
JavierFuentes Avatar answered Sep 22 '22 02:09

JavierFuentes