AoT compiles even when templates are accessing private properties


#1

Hello,

First of all I would like to say that I am completely new to Ionic and also to Angular. Forgive me for any stupid question or comment.

Well, I’m doing some testing to better understand how the AOT compiler works.

I came across this situation where I have a component with private fields, which are accessed in my template, but still the build seems to work perfectly. From what I had understood, this should generate an error.

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {

  private username : string;

  private password : string;  

 //etc etc
}

My template references the fields as follows:


<ion-input [(ngModel)]="username" name="username" type="text" required>

<ion-input [(ngModel)]="password" name="password" type="password" required>

Then, I running the command below and no error was presented:

ionic build --prod

Running app-scripts build: --prod
[22:13:51]  build prod started ... 
[22:13:51]  clean started ... 
[22:13:51]  clean finished in 1 ms 
[22:13:51]  copy started ... 
[22:13:51]  deeplinks started ... 
[22:13:51]  deeplinks finished in 44 ms 
[22:13:51]  ngc started ... 
[22:13:57]  ngc finished in 5.39 s 
[22:13:57]  preprocess started ... 
[22:13:57]  preprocess finished in less than 1 ms 
[22:13:57]  webpack started ... 
[22:13:57]  copy finished in 5.66 s 
[22:14:23]  webpack finished in 25.97 s 
[22:14:23]  uglify started ... 
[22:14:23]  sass started ... 
[22:14:24]  sass finished in 1.35 s 
[22:14:24]  cleancss started ... 
[22:14:25]  cleancss finished in 1.22 s 
[22:14:37]  uglify finished in 14.13 s 
[22:14:37]  postprocess started ... 
[22:14:37]  postprocess finished in 13 ms 
[22:14:37]  lint started ... 
[22:14:37]  build prod finished in 45.69 s 

I found an issue open in Angular github with this same situation: https://github.com/angular/angular/issues/14739.

What was reported in this issue is that the error only appears when running ngc for the 2nd time, because in the first run ngc generates the ngfactories and only in the 2nd run it tries to convert these factories to Javascript and then detects the problem.

marlon@marlon-dell-5480 ~/ $ node_modules/.bin/ngc
marlon@marlon-dell-5480 ~/ $ node_modules/.bin/ngc
	src/pages/login/login.ngfactory.ts:234:32: Property 'username' is private and only accessible within class 'LoginPage'.

This situation can be a problem if someone on the team forgets some private field and breaks the AOT build silently.

Faced with this scenario:

  • Is my build actually using AOT?
  • Is it a reliable build?
  • Do I need to adjust any settings so that the error is shown by ionic-cli?
  • Has there been any change in the AOT regarding the use of private fields that are accessed in the template?

#2

There’s no such thing as a private property in Javascript. Yes, Typescript has a keyword private. It doesn’t mean what you think it means. The word gives a hint to Typescript about how you want to structure your code pre-compile-time. Post-compile-time, no variable is private.

The best way I’ve found to obtain privacy in JS/TS is to stop using classes, and use interfaces instead.


export interface Widgets {
 widgets: Array<Widget>;
}

export function newWidget(): Widget { // return a new widget }

Use that structure (so widget = newWidget() instead of widget = new Widget(), for example) and you’ll get access control and immutability, two things that are almost impossible in JS otherwise.


#3

Thank you @AaronSterling, but that’s not the focus of the matter. What I want to understand is because the Ionic build did NOT generate an error and if the generated build is reliable since it theoretically breaks an AOT compiler rule.


#4

And I’m saying that it’s a time sink to care about this, and much better to avoid the problem entirely. Otherwise your code could break when a new version of Typescript is issued. If you assume private variables do not exist, you’ll be better off.


#5

Hey Marlon, I actually think your question is very valid. I am surprised it doesnt get more attention.

Ionic says use --prod to get AOT but the logic tells us that it won’t be AOT build then… weird.