Skip to content

Instantly share code, notes, and snippets.

@LayZeeDK
Last active February 17, 2020 05:09
Show Gist options
  • Save LayZeeDK/2cd1ff1fc605af6f578a39311b3aba99 to your computer and use it in GitHub Desktop.
Save LayZeeDK/2cd1ff1fc605af6f578a39311b3aba99 to your computer and use it in GitHub Desktop.
Angular Ivy detection logic.
import {
Type,
ɵNG_COMP_DEF,
ɵNG_DIR_DEF,
ɵNG_MOD_DEF,
ɵNG_PIPE_DEF,
} from '@angular/core';
function isIvy(): boolean {
const ng: any = ((self || global || window) as any).ng;
return ng === undefined
|| ng.getComponent !== undefined
|| ng.applyChanges !== undefined;
}
function isIvyComponent(componentType: Type<any>): boolean {
return (componentType as any)[ɵNG_COMP_DEF] !== undefined;
}
function isIvyDirective(directiveType: Type<any>): boolean {
return (directiveType as any)[ɵNG_DIR_DEF] !== undefined;
}
function isIvyModule(moduleType: Type<any>): boolean {
return (moduleType as any)[ɵNG_MOD_DEF] !== undefined;
}
function isIvyPipe(pipeType: Type<any>): boolean {
return (pipeType as any)[ɵNG_PIPE_DEF] !== undefined;
}
@BioPhoton
Copy link

BioPhoton commented Feb 16, 2020

You may want to include your table:

Rendering engine, Angular version, environment window.ngDevMode window.ng MyPipe
View Engine 8 dev object object with properties coreTokens & probe class with static property __annotations__ (array)
View Engine 8 prod undefined object with properties coreTokens & probe class with no own static properties
View Engine 9 dev object object with properties coreTokens & probe class with no own static properties
View Engine 9 prod undefined object with properties coreTokens & probe class with no own static properties
Ivy 8 dev object undefined class with static properties ngPipeDef (object) & decorators (array)
Ivy 8 prod undefined undefined class with static property ngPipeDef (object)
Ivy 9 dev object object with properties getComponent & markDirty class with static property ɵpipe (object)
Ivy 9 prod undefined undefined class with static property ɵpipe (object)

And info on how to use the table:

For Angular versions 8 and 9  

  • View Engine if window.ng is an object with property probe.
  • Ivy if pipe class has own static property ngPipeDef (version 8) or ɵpipe (version 9), both objects.  
  • Development mode if window.ngDevMode is an object.
  • Production mode if window.ngDevMode is undefined or false.

As file to the above gist

@BioPhoton
Copy link

You also may include:

function isIvy(): boolean {
  const ng: any = ((self || global || window) as any).ng;

  return ng === undefined || ng.probe === undefined;
}

"ng unavailable?" = Ivy.
"ng available with probe property?" = View Engine.

@LayZeeDK
Copy link
Author

Thanks for the suggestions, Michael. You left out the header of the table though 😄

@BioPhoton
Copy link

Updated. Sry for the mistake!

@BioPhoton
Copy link

BioPhoton commented Feb 16, 2020

Also here the tests I created, just in case it helps. :)

Functions:

export function getGlobalThis() {
  return (self || global || window) as any;
}

export function isIvy(): boolean {
  const ng: any = getGlobalThis().ng;

  // Is the global ng object is unavailable?
  // ng === undefined in Ivy production mode
  // View Engine has the ng object both in development mode and production mode.
  return (
    ng === undefined ||
    // in case we are in dev mode in ivy
    // `probe` property is available on ng object we use View Engine.
    ng.probe === undefined
  );
}

Tests:

describe('isIvy', () => {
  describe('in ViewEngine Angular 8 + 9', () => {
    it('should return false if ng is defined with probe', () => {
      getGlobalThis().ng = { probe: true };
      expect(isIvy()).toBe(false);
    });
  });
  describe('in Ivy Angular 9', () => {
    it('should return true if ng is undefined', () => {
      getGlobalThis().ng = undefined;
      expect(isIvy()).toBe(true);
    });

    it('should return true if ng.probe is available', () => {
      getGlobalThis().ng = { probe: undefined };
      expect(isIvy()).toBe(true);
    });
  });
});

@LayZeeDK
Copy link
Author

if ng.probe is set

Should be rephrased 😊

@LayZeeDK
Copy link
Author

ng.markDirty changed name to ng.applyChanges in v9.

@BioPhoton
Copy link

Changed to 'is available'

@LayZeeDK
Copy link
Author

But the description doesn't match what's tested. It's backwards. If probe is defined, we're in View Engine.

@BioPhoton
Copy link

BioPhoton commented Feb 16, 2020

Maybe it's too late for me, but isn't this

it(' isIvy should return false if ng is defined with probe', () => {
      getGlobalThis().ng = { probe: true };
      expect(isIvy()).toBe(false);
    });

correct as

If probe is defined, we're in View Engine.

and

 it('should return true if ng is undefined', () => {
      getGlobalThis().ng = undefined;
      expect(isIvy()).toBe(true);
    });

and

    it('should return true if ng.probe is available', () => {
      getGlobalThis().ng = { probe: undefined };
      expect(isIvy()).toBe(true);
    });
  });

is also correct as ng is undefined or ng is defined but probe is undefined?

@LayZeeDK
Copy link
Author

"should return true if ng.probe is undefined"

@BioPhoton
Copy link

See, it was too late. haha.

Thanks! Updated it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment