How to resolve “Function calls are not supported in decorators but 'StoreModule' was called.”

和自甴很熟 提交于 2020-12-04 05:00:14

问题


I've an angular (7) project.

In my package.json, I've a command defined:

{
  "name": "xxx",
  "version": "0.1.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "build-prod": "ng build --prod",
    "test": "ng test",
    "test-ci": "ng test --no-watch --no-progress --browsers=ChromeHeadlessNoSandbox",
    "e2e-ci": "ng e2e --protractor-config=e2e/protractor.conf.js",
    "deploy": "firebase deploy --token $FIREBASE_TOKEN --non-interactive",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  [...]
}

When I just run npm run build-prod locally, everything works nice.

Now I'm trying to have this code executed on my gitlab CI.

For this I've the following .gitlab-ci.yml

image: node:10

build:
  stage: build
  cache:
    paths:
      - node_modules/
  script:
    - npm install --quiet
    - npm run build-prod
  artifacts:
    paths:
      - dist/

test:
  stage: test
  cache:
    policy: pull
    paths:
      - node_modules/
  script:
    # install dependencies to use chrome w/ puppeteer
    - apt update && apt install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
    - npm run test-ci
    - npm run e2e-ci

deploy_prod:
  stage: deploy
  environment:
    name: production
    url: $FIREBASE_URL
  only:
   - master
  dependencies:
    - build
  cache:
    policy: pull
    paths:
      - node_modules/
  script:
    - npm run deploy

But when it runs, I get an error:

Running with gitlab-runner 11.10.0-rc2 (10efa505)
  on docker-auto-scale 72989761
Using Docker executor with image node:10 ...
Pulling docker image node:10 ...
Using docker image sha256:64c810caf95adbe21b5f41be687aa77aaebc197aa92f2b2283da5d57269d2b92 for node:10 ...
Running on runner-72989761-project-XYZ-concurrent-0 via runner-72989761-srm-1555525988-c992ea28...
Initialized empty Git repository in /builds/XXX/YYY/.git/
Fetching changes...
Created fresh repository.
From https://gitlab.com/XXX/YYY
 * [new branch]      13-solve-testing-issues -> origin/13-solve-testing-issues
 * [new branch]      develop                 -> origin/develop
 * [new branch]      master                  -> origin/master
Checking out e61598d8 as 13-solve-testing-issues...

Skipping Git submodules setup
Checking cache for default...
Downloading cache.zip from https://storage.googleapis.com/gitlab-com-runners-cache/project/XYZ/default 
Successfully extracted cache
$ npm install --quiet
npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but npm-shrinkwrap.json was generated for lockfileVersion@0. I'll try to do my best with it!

> ngrx@2.0.1 postinstall /builds/XXX/YYY/node_modules/ngrx
> node postinstall.js

npm WARN ajv-keywords@3.4.0 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/@angular/compiler-cli/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

added 4 packages from 2 contributors and audited 45321 packages in 15.393s
found 27 vulnerabilities (2 low, 5 moderate, 20 high)
  run `npm audit fix` to fix them, or `npm audit` for details
$ npm run build-prod

> YYY@0.1.0 build-prod /builds/XXX/YYY
> ng build --prod


Date: 2019-04-17T18:35:40.652Z
Hash: b0ba2a53437bf05b46d4
Time: 13104ms
chunk {0} runtime.26209474bfa8dc87a77c.js (runtime) 1.41 kB [entry] [rendered]
chunk {1} main.01ecbc0fcff9207e8cde.js (main) 128 bytes [initial] [rendered]
chunk {2} polyfills.a723c36635c3a098c2aa.js (polyfills) 130 bytes [initial] [rendered]
chunk {3} styles.6c94e29121bf3425375a.css (styles) 132 kB [initial] [rendered]
chunk {scripts} scripts.9aa141af6e0119c2bcf8.js (scripts) 581 kB [entry] [rendered]

ERROR in Error during template compile of 'AppModule'
  Function calls are not supported in decorators but 'StoreModule' was called.
node_modules/@ngrx/store/src/ng2.d.ts(1,10): error TS2305: Module '"../../../@angular/core/core"' has no exported member 'OpaqueToken'.
src/app/app.reducer.ts(1,10): error TS2305: Module '"../../node_modules/@ngrx/store"' has no exported member 'ActionReducerMap'.
src/app/app.reducer.ts(1,28): error TS2305: Module '"../../node_modules/@ngrx/store"' has no exported member 'createFeatureSelector'.
src/app/app.reducer.ts(1,51): error TS2305: Module '"../../node_modules/@ngrx/store"' has no exported member 'createSelector'.
src/app/app.module.ts(42,21): error TS2339: Property 'forRoot' does not exist on type 'typeof StoreModule'.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! YYY@0.1.0 build-prod: `ng build --prod`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the YYY@0.1.0 build-prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2019-04-17T18_35_40_678Z-debug.log
ERROR: Job failed: exit code 1

I'm quite new with angular and gitlab. Do you see why can be wrong, or how to find my issue?

EDIT Here is my current tsconfig file:

{
    "compileOnSave": false,
    "compilerOptions": {
        "baseUrl": "./",
        "outDir": "./dist/out-tsc",
        "sourceMap": true,
        "declaration": false,
        "module": "es2015",
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es5",
        "typeRoots": [
            "node_modules/@types"
        ],
        "lib": [
            "es2018",
            "dom"
        ]
    },
    "angularCompilerOptions":{

        "skipTemplateCodegen": false,
        "strictMetadataEmit": false,
    }
}

EDIT 2 Here is my app.module.ts:

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LocationStrategy, PathLocationStrategy } from '@angular/common';
import { AppRoutes } from './app.routes';


import { AppComponent } from './app.component';
import { AppProfileComponent } from './app.profile.component';
import { AppMenuComponent, AppSubMenuComponent } from './app.menu.component';
import { AppBreadcrumbComponent } from './app.breadcrumb.component';
import { AppTopBarComponent } from './app.topbar.component';
import { AppFooterComponent } from './app.footer.component';


import { BreadcrumbService } from './breadcrumb.service';
import { LayoutModule } from './layout/layout.module';
import { BeersModule } from './beers/beers.module';


import { AngularFireModule } from '@angular/fire';
import { environment } from '../environments/environment';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { PrimeNgModule } from './primeng/primeng.module';
import { StoreModule } from '@ngrx/store';
import {reducers} from './app.reducer';

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        AppRoutes,
        HttpClientModule,
        BrowserAnimationsModule,
        LayoutModule,
        BeersModule,
        AngularFireModule.initializeApp(environment.firebase),
        AngularFireAuthModule,
        PrimeNgModule,
        StoreModule.forRoot(reducers)
    ],
    declarations: [
        AppComponent,
        AppMenuComponent,
        AppSubMenuComponent,
        AppProfileComponent,
        AppBreadcrumbComponent,
        AppTopBarComponent,
        AppFooterComponent,
    ],
    providers: [
        { provide: LocationStrategy, useClass: PathLocationStrategy },
         BreadcrumbService
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

EDIT

I changed my yml file to have node: latest.

Now I've different errors:

http://pasted.co/e311ee1b


回答1:


EDIT

For starters, you have a dependency for ngrx as well as @ngrx/store, and only the latter is correct.

You are running a postinstall script from there as well.

Be careful when you npm add dependencies as you might be adding malicious code to your application if you are not paying attention.

Second, you are importing @ngrx/core which is not needed since version 4 of NgRx, and you are using ^7.4.0. Make sure to read the migration guides if you are upgrading important functionality in your app:

https://ngrx.io/guide/migration/v4

and/or

https://ngrx.io/guide/migration/v7

OLD ANSWER

To inject the root reducers into your application, use an InjectionToken and a Provider to register the reducers through dependency injection.

https://github.com/ngrx/platform/blob/master/docs/store/api.md#injecting-reducers

If you are interested in the details:

https://github.com/angular/angular/blob/master/packages/compiler/design/architecture.md#need-for-static-value-resolution

Can you show us in what way you are setting up NgRx in your application? You need to register your reducers through dependency injection in order to make AOT compilation work properly.

app.module.ts

import { StoreModule } from '@ngrx/store';
import { reducerToken, reducerProvider } from './index';

@NgModule({
    declarations: [],
    imports: [StoreModule.forRoot(reducerToken)],
    providers: [reducerProvider]
})

index.ts

import { InjectionToken } from '@angular/core';
import { ActionReducerMap } from '@ngrx/store';


export const reducers: ActionReducerMap<any> = {
  // reducers
}

export const reducerToken = new InjectionToken<ActionReducerMap<AppState>>('Registered Reducers');

export const reducerProvider = [
    { provide: reducerToken, useValue: reducers }
];



回答2:


I can't figure out your issue exactly, but about function calls are not supported in decorators, at the exported module we can make:

@NgModule({
  declarations: [...],
  imports: [
    ...
  ],
  providers: [...],
  bootstrap: [...]
})

export class AppModule { }
@NgModule({})
export class ToSpaceAppModule {
  static forRoot(): ModuleWithProviders {
    const providers = [];
    return {
      ngModule: AppModule,
      providers
    };
  }
}

'somewhere'

import { ToSpaceAppModule } from '../src/app/app.module';

export function fromSpaceFactory() {
  return import('../src/app/app.module').then(m => m.ToSpaceAppModule );
}

@NgModule({
  declarations: [...],
  imports: [
    ...
    ToSpaceAppModule 
  ],
  providers: [
    {
      provide: ToSpaceAppModule ,
      useFactory: fromSpaceFactory
    }
  ],
  bootstrap: [...]
})
export class AppModule { }



来源:https://stackoverflow.com/questions/55734185/how-to-resolve-function-calls-are-not-supported-in-decorators-but-storemodule

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!