Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular build optimizer throws error on decorators #217

Open
aciccarello opened this issue Feb 16, 2018 · 2 comments
Open

Angular build optimizer throws error on decorators #217

aciccarello opened this issue Feb 16, 2018 · 2 comments

Comments

@aciccarello
Copy link
Collaborator

The Angular CLI actually works pretty well with bundling hybrid ng-metadata applications. However the production build does not like 3rd party decorators (angular/angular#14323).

ERROR in legacy\my.module.ts(17,2): Error during template compile of 'MyModule'
  Only initialized variables and constants can be referenced in decorators because the value of this variable is needed by the template compiler in 'NgModule'
    'NgModule' references 'NgModule'
      'NgModule' references 'NgModule'
        'NgModule' is not initialized at ..\ng-metadata\src\core\directives\decorators.ts(233,22).

If possible ng-metadata should find a way to make the compiler happy and enable AOT on Angular components while keeping the Angular.js/ng-metadata components JIT.

@aciccarello
Copy link
Collaborator Author

I was able to get an AOT build working on my hybrid application by reimplementing the class decorators as simple functions with a helper function in the actual decorator function. The Angular compiler didn't complain about the parameter decorators.

export function annotateClass(target, annotationInstance) {
  if (annotationInstance instanceof InjectableMetadata) {
    annotationInstance.id = annotationInstance.id || globalKeyRegistry.get(target);
  }

  const annotations = reflector.ownAnnotations(target) || [];
  annotations.push(annotationInstance);
  reflector.registerAnnotations(annotations, target);

  return target;
}

export function Directive(params) {
  return function decorator(target) {
    return annotateClass(target, new DirectiveMetadata(params));
  }
}

The only problem is that the key registry was throwing a type error because one of the internal types was not exported.

ERROR in node_modules/ng-metadata/src/core/di/key.d.ts(1,41): error TS2304: Cannot find name 'KeyRegistry'.

It should be possible to write a PR which re-implements the decorators in a way which satisfies the angular compiler.

@ashpr
Copy link

ashpr commented Apr 15, 2019

If anyones plagued by this.. we have a solution. It's NOT nice but we're actively moving from ng-metadata to ngUpgrade so it wasn't a big deal for us.

import * as m from 'ng-metadata/core';

const Injectable = m['Injectable' + ''];
const Inject = m['Inject' + ''];

I would advocate finding a better solution as I personally hate this but it worked for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants