Skip to content

Prod Mode Compiling Out TypeScript decorator metadata from external project #10584

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

Closed
amcdnl opened this issue May 1, 2018 · 12 comments
Closed
Assignees

Comments

@amcdnl
Copy link

amcdnl commented May 1, 2018

Observed behavior

The cli in prod mode is compiling out the typescript decorator (custom decorator) metadata from a external project compiled using ng-packagr.

An example of the decorator metadata would be:

__decorate([
    Action(Navigate),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Navigate]),
    __metadata("design:returntype", void 0)
], RouterState.prototype, "navigate", null);

The result can be seen in this screenshot on the left:

img

It seems to be related to only external projects. I'm using the same custom decorator used in this code in my project and it works fine.

Desired behavior

It not to compile this out.

Repro steps

  • npm i @ngxs/router-plugin @ngxs/store
  • Include the store and router plugin in your project like so:
@NgModule({
  imports: [
    NgxsModule.forRoot([]),
    NgxsRouterPluginModule.forRoot()
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}
  • Build the application in production
  • Inspect the source and note the decorate metadata was compiled out

For reference here is the compiled code

Versions

Node 10
Npm 6
Mac
"@angular/cli": "^6.0.0-rc.8",

Mention any other details that might be useful (optional)

@amcdnl amcdnl changed the title Uglify Compiling out TypeScript decorator metadata from external project Prod Mode Compiling Out TypeScript decorator metadata from external project May 1, 2018
@filipesilva
Copy link
Contributor

@amcdnl does this repro fail at runtime with the changes you listed? If not, can you give me a repro that fails so I can see something failing and then try to fix it?

@deebloo
Copy link
Contributor

deebloo commented May 1, 2018

What is worth noting is that the router plugin mentioned here uses ngxs internally and is then packaged with ng-packagr

@filipesilva filipesilva self-assigned this May 1, 2018
@filipesilva
Copy link
Contributor

filipesilva commented May 2, 2018

I looked into this a bit and it doesn't seem to have anything to do with production mode.

Using this src/app/app.component.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgxsRouterPluginModule } from '@ngxs/router-plugin';
import { NgxsModule } from '@ngxs/store';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    NgxsModule.forRoot([]),
    NgxsRouterPluginModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

And Angular CLI 6.0.0-rc.8, ng serve --aot will show the following message at runtime:

Uncaught Error: StaticInjectorError(AppModule)[RouterState -> Router]: 
  StaticInjectorError(Platform: core)[RouterState -> Router]: 
    NullInjectorError: No provider for Router!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:979)
    at resolveToken (core.js:1232)
    at tryResolveToken (core.js:1182)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1077)
    at resolveToken (core.js:1232)
    at tryResolveToken (core.js:1182)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1077)
    at resolveNgModuleDep (core.js:9235)
    at _createClass (core.js:9276)
    at _createProviderInstance$1 (core.js:9252)

I'm not sure why this happens but it doesn't seem like a Uglify or Build Optimizer problem.

@filipesilva
Copy link
Contributor

Btw if this isn't the same error as you are seeing, please provide a reproduction that I can clone and shows the right one.

@deebloo
Copy link
Contributor

deebloo commented May 2, 2018

Can you try adding the router module and see if that gets you to the wrror?

@deebloo
Copy link
Contributor

deebloo commented May 2, 2018

*error

@amcdnl
Copy link
Author

amcdnl commented May 2, 2018

@filipesilva = whops, I forgot to tell you to include the angular router. There is no runtime error, it compiles out the code so nothing actually runs on those decorators.

@amcdnl
Copy link
Author

amcdnl commented May 2, 2018

@filipesilva @deebloo - Here is a github repo showing the issue - https://github.com/amcdnl/cli-prod-issue

Just do npm start and click the click me button. Nothing happens. If you remove the --prod flag it will throw a error saying no route matches (desired). Inspect the compiled code with source maps off in dev tools and you will see the decorator I mentioned removed from router-plugin module.

@amcdnl
Copy link
Author

amcdnl commented May 2, 2018

I also fixed an issue where my TypeScript enums were getting compiled out too. I had a enum like:

export enum Foo {
  Bar = 'BAR'
}

and it was resolving to undefined. I rewrote it to be:

export const enum Foo {
   Bar = 'BAR'
}

and it worked then. I wonder if that is related to this too.

@filipesilva
Copy link
Contributor

@amcdnl I have used your repro and can confirm I see the problem. @clydin and I have analysed what's happening and can explain what's going wrong.

These libraries have "sideEffects": false in their package.json, which prompts advanced optimizations, but they actually have side effects.

If you look at your gist: https://gist.github.com/amcdnl/0236f4849e2941b279113a5589cef44b#file-compiled-js-L207-L230:

console.log('!!!!!!!');
__decorate([
    Action(Navigate),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Navigate]),
    __metadata("design:returntype", void 0)
], RouterState.prototype, "navigate", null);

The toplevel console.log is a side effect (which will be removed), and so is any __decorate call.

I am not sure if you added "sideEffects": false yourself, or if it was added automatically by ng-packagr, but at the moment it should be removed.

If you remove it directly in your node_modules you will also need to delete node_modules/.cache and node_modules/@angular-devkit/build-optimizer/src/.cache since these will cache code for production builds.

@amcdnl
Copy link
Author

amcdnl commented May 2, 2018

Can confirm adding that fixed the issue. thanks for your help!

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants