typescript 如何摆脱 Angular aot 编译中装饰器不支持的函数调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48283479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:10:26  来源:igfitidea点击:

How to get rid of Function calls are not supported in decorators in Angular aot compiling?

javascriptangulartypescripthighchartsangular-cli

提问by Anis Tissaoui

I am testing a HighchartsAngular2x Wrapper. At first, I had no problem using Angular CLI (1.6.1) "ng serve" and profiling performance with Chrome. Then, i tried to use ahead-of-time compiling to see how that affects the performance.

我正在测试HighchartsAngular2x Wrapper。起初,我在使用 Angular CLI (1.6.1)“ng serve”和 Chrome 性能分析方面没有问题。然后,我尝试使用提前编译来查看这如何影响性能。

So, using:

所以,使用:

ng serve --aot

I get the following error:

我收到以下错误:

ERROR in Error during template compile of 'AppModule'
  Function calls are not supported in decorators but 'ChartModule' was called.

Now, i know that aot generates factory code for modules and somehow "transformes" templates to VanillaJS, things get a bit tricky here and i couldn't understand how ngc is going to generate factory code for a module that requires an external library.

现在,我知道 aot 为模块生成工厂代码并以某种方式将模板“转换”为 VanillaJS,这里的事情有点棘手,我无法理解 ngc 将如何为需要外部库的模块生成工厂代码。

I got this App.Module.ts:

我得到了这个 App.Module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ChartModule } from 'angular2-highcharts';

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

declare var require: any;
export function getHighchartsModule() {
  return  require('highcharts');
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ChartModule.forRoot(getHighchartsModule) // This causes the error
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

My Package.json dependencies :

我的 Package.json 依赖项:

"dependencies": {
    "@angular/animations": "^5.0.0",
    "@angular/common": "^5.0.0",
    "@angular/compiler": "^5.0.0",
    "@angular/core": "^5.0.0",
    "@angular/forms": "^5.0.0",
    "@angular/http": "^5.0.0",
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "angular2-highcharts": "^0.5.5",
    "core-js": "^2.4.1",
    "rxjs": "^5.5.2",
    "zone.js": "^0.8.14"
  }

My questions are : Is there anything i can do here to avoid the mentioned compiling error ? Can anyone explain why does this happen ? (optional)

我的问题是:我可以在这里做些什么来避免提到的编译错误?谁能解释为什么会这样?(选修的)

采纳答案by Anis Tissaoui

Mentioning the Github issue here. The following solution worked for me.

这里提到 Github 问题。以下解决方案对我有用。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

// Angular Highcharts Imports
import {HighchartsStatic} from 'angular2-highcharts/dist/HighchartsService'; 
import { ChartModule } from 'angular2-highcharts';

// Factory Function
export function highchartsFactory() {
  var hc = require('highcharts');
  return hc;
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ChartModule // Import Module Here
  ],
  providers: [ // Provide Service Here
    {
      provide: HighchartsStatic,
      useFactory: highchartsFactory 
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

回答by dasfdsa

This is a problem with angular in general. Angular compiler wants the forRootcode to be completely static.

这通常是 angular 的问题。Angular 编译器希望forRoot代码完全静态。

As an example, in the following code even the assignment of the static variable with cause this error:

例如,在下面的代码中,即使是静态变量的赋值也会导致此错误:

static forRoot(config: MyConfig): ModuleWithProviders {
    MyConfigService.config = config;// This line with cause an error
    return {
      ngModule: HttpTrackerLibModule,
    };
  }

If you are notlibrary creator there is nothing much you can do but try library-specific solutions like the one above. But if you are a library creator you can try a static approach as follows:

如果您不是库的创建者,除了尝试上述特定于库的解决方案外,您无能为力。但是,如果您是库创建者,则可以尝试以下静态方法:

  1. Create an injection token:

    export const USER_OPTIONS = new InjectionToken<MyConfig>('USER_OPTIONS');

  2. Provide the token in your library Module

  1. 创建注入令牌:

    export const USER_OPTIONS = new InjectionToken<MyConfig>('USER_OPTIONS');

  2. 在您的库模块中提供令牌

static forRoot(config: MyConfig): ModuleWithProviders {
            return {
                ngModule: HttpTrackerLibModule,
                providers: [{
                    provide: USER_OPTIONS,
                    useValue: config
                }],
            };
        }

  1. Use the token using DI elsewhere:
  1. 在别处使用 DI 使用令牌:

export class ConfigService {
  constructor(@Inject(USER_OPTIONS) private _config: MyConfig) {

  }
}

回答by NoizyCr1cket

I've encountered this same issue. Try removing the getHighchartsModuleexport from your App.Module.tsand put the exported function in its own file. Then import it into App.Module.ts.

我遇到过同样的问题。尝试getHighchartsModule从您的导出中删除App.Module.ts并将导出的函数放在其自己的文件中。然后将其导入到App.Module.ts.

I have not figured out why this happens yet.

我还没有弄清楚为什么会发生这种情况。