• Stars
    star
    297
  • Rank 140,075 (Top 3 %)
  • Language
    TypeScript
  • Created about 8 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Sandbox for testing Angular 2's AoT specifically what expressions break it

Angular 2 AoT SandBox

This repo is used to formalize what we can and cannot do with AoT (through ngc or @ngtools/webpack).

To run specific test case like control:

node sandbox-loader.js control

The default is to use ngc for AoT, but you can also use @ngtools/webpack:

node sandbox-loader.js control ngtools

or JiT:

node sandbox-loader.js control jit

The bundle files are inside ./dist/, and to host:

npm run start

Current Status

Test AoT With ngc AoT With @ngtools/webpack JiT
control
form-control
func-in-string-config
jquery
template-variable
template-expression
mut-property-decorator
nomut-property-decorator
angular-redux-store
ngrx
ngrx-compose
arrow-function-exports
default-exports
form-control-error
func-as-variable-export
func-declaration-export
func-in-declarations
func-in-providers
func-in-providers-useFactory
func-in-providers-useValue
func-in-routes
interpolated-es6
property-accessors
private-contentchild
private-hostbinding
private-input
private-output
private-property
private-viewchild
service-with-generic-type-param

AoT Do's and Don'ts

This section explains the cases listed above, and will show how each of them fails and works.

arrow-function-exports 🔝

Arrow function does not work with AoT when it is passed to an NgModule.

Don't:

export const couterReducer = (state, action: Action) => {
  // ...
}

Do:

export function counterReducer(state, action: Action) {
  // ...
}

control 🔝

This is used as a simplest working case.

default-exports 🔝

Default exports are not supported with AoT.

Don't:

export default class AppComponent {};

Do:

export class AppComponent {};

form-control 🔝

Use this.helloForm.controls["greetingMessage"] to retrieve form control is fine.

form-control-error 🔝

The syntax errors? is not supported by AoT.

Don't:

{{helloForm.controls["greetingMessage"].errors?.minlength}}

Do:

{{helloForm.controls["greetingMessage"].hasError("minlength")}}

func-as-variable-export 🔝

Export function as variable is fine with AoT except when it is passed to an NgModule.

Don't:

//foo.ts
export const foo = function foo(state: number) {
  return "foo" + state;
}

//app.module.ts
@NgModule({
  imports: [
    //...
    FooModule.provideFoo(foo),
  ],
  //...
})
export class AppModule {};

Do:

//foo.ts
export function foo(state: number) {
  return "foo" + state;
}

//app.module.ts
@NgModule({
  imports: [
    //...
    FooModule.provideFoo(foo),
  ],
  //...
})
export class AppModule {};

func-declaration-export 🔝

This is a fixed version of func-as-variable-export.

func-in-declarations 🔝

Don't:

function someLoader() {...}
@NgModule({
  //...
  declarations: someLoader(),
  //...
})
export class AppModule {};

Apply @angular/router or other Angular logic to re-implement the same thing.

func-in-providers 🔝

Pass a result of function to providers is not supported by AoT.

Don't:

//services/service-providers.ts
import { AppService } from "./app.service";
const services = {
  AppService: AppService
};

export function getService(k) {
  return services[k];
}
export const serviceProviders = Object.keys(services).map(getService);

//app.module.ts
import { serviceProviders } from "./services/service-providers";
@NgModule({
  //...
  providers: serviceProviders
})
export class AppModule {};

Do:

//services/service-providers.ts
import { AppService } from "./app.service";
export const serviceProviders = [
  AppService
];

//app.module.ts
import { serviceProviders } from "./services/service-providers";
@NgModule({
  //...
  providers: serviceProviders
})
export class AppModule {};

func-in-providers-useFactory 🔝

Instead of using function directly, export it first in another module and import it back.

Don't:

@NgModule({
  //...
  providers: [
    { provide: AppService, useFactory: () => { return { name: "world test" }; }},
  ],
  //...
})
export class AppModule {};

Do:

import { randomFactory } from "./random.factory.ts"
@NgModule({
  //...
  providers: [
    { provide: AppService, useFactory: randomFactory }},
  ],
  //...
})
export class AppModule {};

func-in-providers-useValue 🔝

This case only fails when the passed value is generated by a nested function. If the foo inside foo.ts is not returning another function, then it will pass. Another solution is to replace useValue with useFactory and set it to use bar instead of barConst.

Don't:

//foo.ts
export function foo() { return function() { return {}; }; };
export const fooConst = foo();

//bar.ts
import { fooConst } from "./foo";
export function bar() { return fooConst(); }
export const barConst = bar();

//app.module.ts
//...
import { barConst } from "./bar";

@NgModule({
  //...
  providers: [ { provide: AppService, useValue: barConst }]
})
export class AppModule {};

Do:

//foo.ts
export function foo() { return {}; };
export const fooConst = foo();

//app.module.ts
//...
import { fooConst } from "./bar";

@NgModule({
  //...
  providers: [ { provide: AppService, useValue: fooConst }]
})
export class AppModule {};

or

//foo.ts
export function foo() { return function() { return {}; }; };
export function fooFactory() {
   return foo();
}
//app.module.ts
//...
import { fooFactory } from "./foo";

@NgModule({
  //...
  providers: [ { provide: AppService, useFactory: fooFactory }]
})
export class AppModule {};

func-in-routes 🔝

Direct use of function in route is not supported by AoT. Either avoid using it or export it from other module.

Don't:

function random() {
  return [{
    path: "",
    component: AppViewComponent
  }];
}
const SAMPLE_APP_ROUTES: Routes = random();

Do:

const SAMPLE_APP_ROUTES: Routes = [{
  path: "",
  component: AppViewComponent
}];

or

import { random } from "./random.routes.ts";
const SAMPLE_APP_ROUTES: Routes = random();

func-in-string-config 🔝

Function in string configuration is supported by AoT.

interpolated-es6 🔝

Don't:

@Component({
  selector: "app",
  template: `Hello ${1 + 1}`
})
export class AppComponent {};

Do:

@Component({
  selector: "app",
  template: `Hello {{value}}`
})
export class AppComponent {
  value:number = 1 + 1;
};

jquery 🔝

To use jQuery with AoT, one way is to use the webpack.ProvidePlugin to provide jquery as global variable; another way is to inject jquery as a service like this:

//...
const $ = require("jquery");
export function jqueryFactory () {
  return $;
}
@NgModule({
  //...
  providers: [
    { provide: "JqueryService", useFactory: jqueryFactory},
  ],
  bootstrap: [AppComponent]
})
export class AppModule {};

Notice that useValue here does not work.

mut-property-decorator 🔝

Mutating property decorator is supported by ngc, but does not work with @ngtools/webpack, because @ngtools/webpack explicitly remove all custom decorators. Details can be found here: angular-redux/store#236.

Desired effect of this case is that Hello World 42 instead of Hello 42 should be displayed.

angular-redux 🔝

Setting up basic angular-redux/store is fine with AoT. This includes the @select decorator, both with @ngtools/webpack and raw ngc.

ngrx 🔝

Setting up basic ngrx is fine with AoT. This includes their @Effect decorator as well.

ngrx-compose 🔝

Direct use of compose does not work with AoT, it requires a wrapper.

Don't:

//reducers/index.ts
const reducers = {
  counter: fromCounter.counterReducer,
};
const reducer: ActionReducer<State> = compose(storeLogger(), combineReducers)(reducers);

//app.module.ts
//...
import { reducer } from "./reducers";
@NgModule({
  imports: [
    BrowserModule,
    StoreModule.provideStore(reducer)
  ],
  //...
})
export class AppModule {}

Do:

//reducers/index.ts
const reducers = {
  counter: fromCounter.counterReducer,
};
const developmentReducer: ActionReducer<State> = compose(storeLogger(), combineReducers)(reducers);
export function reducer(state: any, action: any) {
  return developmentReducer(state, action);
};

//app.module.ts
//...
import { reducer } from "./reducers";
@NgModule({
  imports: [
    BrowserModule,
    StoreModule.provideStore(reducer)
  ],
  //...
})
export class AppModule {}

nomut-property-decorator 🔝

No-mutating property decorator is supported by ngc, but does not work with @ngtools/webpack, because @ngtools/webpack explicitly remove all custom decorators. Details can be found here: angular-redux/store#236.

Desired effect of this case is that console should raise errors because we are trying to change a @ReadOnly property.

private-contentchild 🔝

Don't:

export class TabComponent {
  //...
  @ContentChildren(PaneDirective) private panes: QueryList<PaneDirective>;
  //...
}

Do:

export class TabComponent {
  //...
  /** @internal */
  @ContentChildren(PaneDirective) panes: QueryList<PaneDirective>;
  //...
}

private-hostbinding 🔝

Don't:

export class NameDirective {
  @HostBinding("class.world") private isWorld: boolean = false;
}

Do:

export class NameDirective {
  /** @internal */
  @HostBinding("class.world") isWorld: boolean = false;
}

private-input 🔝

Don't:

export class NameComponent {
 @Input() private name: String;
};

Do:

export class NameComponent {
  /** @internal */
 @Input() name: String;
};

private-output 🔝

Don't:

export class NameComponent {
 @Output() private onClicked = new EventEmitter<boolean>();
 //...
};

Do:

export class NameComponent {
  /** @internal */
 @Output() onClicked = new EventEmitter<boolean>();
 //...
};

private-property 🔝

Don't:

export class AppComponent {
  private name: string;
  constructor() {
    this.name = 'World';
  }
}

Do:

export class AppComponent {
  /** @internal */
  name: string;
  constructor() {
    this.name = 'World';
  }
}

private-viewchild 🔝

Don't:

export class AppComponent implements AfterViewInit {
  @ViewChild(ChildDirective) private child: ChildDirective;

  ngAfterViewInit() {
    console.log(this.child.value);
  }
};

Do:

export class AppComponent implements AfterViewInit {
  /** @internal */
  @ViewChild(ChildDirective) child: ChildDirective;

  ngAfterViewInit() {
    console.log(this.child.value);
  }
};

property-accessors 🔝

The es6 property accessors are not supported by AoT if it is passed to an NgModule.

Don't:

import { ERROR, WARNING } from "./definitions";

export function handler1() {};
export function handler2() {};
export const ErrorEventHandlers = {
  [ERROR]: {
    handler: handler1
  },
  [WARNING]: {
    handler: handler2
  }
};

Do:

export function handler1() {};
export function handler2() {};
export const ErrorEventHandlers = {
  'ERROR': {
    handler: handler1
  },
  'WARNING': {
    handler: handler2
  }
};

service-with-generic-type-param 🔝

Don't:

export class AppComponent {
  greeting: string;
  constructor(helloService: HelloService<boolean>) {
    this.greeting = helloService.getHello(true);
  }
};

The generic type parameter is not supported in Angular, and there is more detail.

template-expression 🔝

Assign expression like greeting + answer to template is supported by AoT.

template-variable 🔝

Assign variable like greeting to template is supported by AoT.

More Repositories

1

augury

Angular Debugging and Visualization Tools
TypeScript
2,008
star
2

redux-beacon

Analytics integration for Redux and ngrx/store
TypeScript
668
star
3

angular-ssr

Angular 4+ server-side rendering solution compatible with @angular/material, jQuery, and other libraries that touch the DOM (as well as providing a rich feature set!)
TypeScript
279
star
4

angular-devtools

Moved to the Angular organization.
TypeScript
255
star
5

ngCourse2

An Angular Course from Rangle.io
TypeScript
184
star
6

radius

A design system accelerator
TypeScript
173
star
7

augury-labs

Experimental Angular developer tools
TypeScript
89
star
8

stripe-eventbridge

Connect Stripe events to AWS EventBridge
JavaScript
72
star
9

angular2-starter

Angular 2 Starter Repo
JavaScript
60
star
10

radius-tracker

Measure adoption of your design system
TypeScript
56
star
11

rangle-starter

JavaScript
48
star
12

mibank-micro-frontends

Demonstration of Micro Frontend Architecture.
JavaScript
43
star
13

jwt-role-based-authentication-examples

Implement the same backend using graphql, nestjs and deno.
TypeScript
34
star
14

schematics-angular

Angular Schematics for adding features to an existing angular project to improve productivity and organization-wide consistency
TypeScript
34
star
15

hackstack

A library for building AngularJS apps with broken APIs that are delivered late.
JavaScript
32
star
16

angular-training-slides

Slides for the Angular 2 training
HTML
29
star
17

angular-ngrx-example

Angular @ngrx example illustrating best practices
TypeScript
28
star
18

federated-modules-typescript

Use Webpack5 Module Federation with TS/React - Type-safe MonoRepo setup
JavaScript
18
star
19

pgdays-codepush-demo

JavaScript
14
star
20

angular-training-examples

Blog application for Angular 2 training
TypeScript
13
star
21

code-push-demo

An example of how to use CodePush with an Ionic/Cordova app.
JavaScript
11
star
22

react-native-workshop

JavaScript
10
star
23

radius-monorepo-react

Radius Monorepo Configuration for React
TypeScript
9
star
24

Stripe-shop-backend

A starter kit for Stripe Payments running on AWS lambda's with DynamoDB. Implements a basic Catalog and payment. Support Terminal and Stripe Elements.
TypeScript
8
star
25

augury-examples

A repo containing the augury example apps.
TypeScript
7
star
26

react-native-example

React-native and redux example package
JavaScript
7
star
27

serve-webpack-client

Helper module for serving webpack-related client code from a nodejs server.
JavaScript
6
star
28

rangle-investing

RangleBank Investing App
TypeScript
5
star
29

radius-angular

TypeScript
4
star
30

express-jwt-jwks

Simple JWT auth using JWKS key sets for Express. Wraps express-jwt and jwks-rsa. AWS Cognito compatible.
JavaScript
4
star
31

custom-angular-schematic-demo

Custom schematics for libraries
TypeScript
4
star
32

headless-workshop

TypeScript
4
star
33

radius-workspace

Main workspace for the new version of Radius
TypeScript
4
star
34

figma-plugin-missing-library-usage-finder

Figma Plugin to find instances or styles by name, e.g. to find missing library usage
TypeScript
4
star
35

vue-3d

3D visualization demo for Hack Western 5.
Vue
3
star
36

bridge-transit-app-cohort-2

JavaScript
3
star
37

react-native-netflix-clone

Basic Netflix clone app built with React Native
TypeScript
3
star
38

augury-site

Augury's Documentation Site
JavaScript
3
star
39

invision-dsm-utlities

Utility scripts to help integrate InVision Design System Manager (DSM) into your front-end codebase.
TypeScript
3
star
40

catch-webhooks

A webhook catcher with a web UI. See a transcript log of webhook events that reach your endpoint in a nice annotatable web interface.
JavaScript
3
star
41

rangle-academy-unit-testing

Workshop for Unit Testing
JavaScript
3
star
42

angular-18-demos

TypeScript
3
star
43

stripe-ts-react-redux-saga

Demo of Stripe Elements & Terminal in React/Redux/Sagas using Typescript
TypeScript
3
star
44

react-training-oct-2

JavaScript
2
star
45

angular-training

Integrated Angular training materials
Shell
2
star
46

angular-testing-workshop

TypeScript
2
star
47

react-native-workshop-1

Objective-C
2
star
48

react-training-sep-25

JavaScript
2
star
49

gitub-action-template-example

Example of setting up Github action workflow templates within Organization
2
star
50

a11y-violations-crawler

A performant webpage-crawler that will run each page through axe-core to display and/or store violations related to it for reporting.
CSS
2
star
51

rangle-type-scale

JavaScript
2
star
52

angular-performance-meetup

Sample application to show how to improve performance in an Angular app
CSS
2
star
53

bridge-photo-map-app

JavaScript
2
star
54

angular-training-app

Sample application for learning Angular 2
JavaScript
2
star
55

ng-apollo-story

TypeScript
2
star
56

angular-headless-cms

TypeScript
2
star
57

test-automation

Any code related to testing such as automation frameworks or utilities for manual testing.
HTML
1
star
58

koast-db-utils

JavaScript
1
star
59

koast-admin-app

client app to admin a koast server
JavaScript
1
star
60

radius-token-tango

Suite of tools to connect Design Tokens to Repositories, facilitating Figma workflows
TypeScript
1
star
61

a11y-test-automation

TypeScript
1
star
62

angular-schematic-patterns

TypeScript
1
star
63

stripe-payment-demo

Vue
1
star
64

ng-blog-live-code

Live Coded Blog For Teaching Angular
TypeScript
1
star
65

react-native-training

Rangle.io React Native Training
JavaScript
1
star
66

playingHere

JavaScript
1
star
67

graphql-pt1-workshop-slides

Slides and speaker notes for GraphQL Part 1 workshop
CSS
1
star
68

jekyll-starter

A Gulp based Jekyll Starter
JavaScript
1
star
69

contentful-custom-map-editor

Custom Image Map Editor for Contentful
TypeScript
1
star
70

angular-book-examples

TypeScript
1
star
71

apollo-rest-example

Apollo Rest API Server Adaptor Example
TypeScript
1
star
72

serverless-app-poc

A serverless application that provides subscription-based online learning content managed by headless CMS.
JavaScript
1
star
73

bridge-lcbo-app-cohort-2

JavaScript
1
star
74

ai-alt-text-generator

TypeScript
1
star
75

styled-system-workshop

Programming Design Systems with Styled-System Workshop
JavaScript
1
star