简体   繁体   English

如何在 Angular 的 app.module 中使用使用条件导出的 class?

[英]How can I use a class that use conditional export in Angular's app.module?

This question is the beggining of the story if you want to understand it deeper.如果您想更深入地了解它, 这个问题就是故事的开始。

I'm trying to use this class in app.module:我正在尝试在 app.module 中使用这个 class:

import { Injectable } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';
import { environment } from '../../../environments/environment';

@Injectable({ providedIn: 'root' })
export class MockKeycloakService { 

    init(ign: any) {
        console.log('[KEYCLOAK] Mocked Keycloak call');
        return Promise.resolve(true);
    }

    getKeycloakInstance() {
        return {
            loadUserInfo: () => {
                let callback;
                Promise.resolve().then(() => {
                    callback({
                    username: '111111111-11',
                    name: 'Whatever Something de Paula',
                    email: 'whatever@gmail.com',
                  });
                });
                return { success: (fn) => callback = fn };
            }
        } as any;
    }    
    login() {}      
    logout() {}
}

const exportKeycloak = 
    environment.production ? KeycloakService : MockKeycloakService;    
export default exportKeycloak; 

This conditional export fakes keycloak call to use in local development and returns the real class in production.此条件导出伪造 keycloak 调用以在本地开发中使用,并在生产中返回真正的 class。

This is the app.module I used:这是我使用的 app.module:

<...>
import { KeycloakAngularModule } from 'keycloak-angular';
import KeycloakService from './shared/services/keycloak-mock.service';
import { initializer } from './app-init';
<...>

    imports: [
        KeycloakAngularModule,
         <...>  
    ],
    providers: [
        <...>,
        {
            provide: APP_INITIALIZER,
            useFactory: initializer,
            multi: true,
            deps: [KeycloakService, <...>]
        },
        <...>
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

related app-init:相关的应用程序初始化:

import KeycloakService from './shared/services/keycloak.mock.service';
import { KeycloakUser } from './shared/models/keycloakUser';

import { environment } from '../environments/environment';
<...>

export function initializer(
    keycloak: any,
    <...>
): () => Promise<any> {
    return (): Promise<any> => {
        return new Promise(async (res, rej) => {
            <...>    
            await keycloak.init({
                 <...>
            }).then((authenticated: boolean) => {
                if (!authenticated) return;
                keycloak
                    .getKeycloakInstance()
                    .loadUserInfo()
                    .success(async (user: KeycloakUser) => {
                        <...>
                    })    
            }).catch((err: any) => rej(err));
            res();
        });
    };

All works fine in the development mode.在开发模式下一切正常。 I can use the mocked call, and if I enable production in environment.config it makes the real call.我可以使用模拟调用,如果我在 environment.config 中启用生产,它会进行真正的调用。 But when I try to build it to publish in production server I get the following error:但是当我尝试构建它以在生产服务器中发布时,我收到以下错误:

ERROR in Can't resolve all parameters for ɵ1 in /vagrant/frontend/src/app/app.module.ts: (?, [object Object], [object Object]).

My guess is that the builder task can't understand the conditional export in the mocked class to use in app.module.我的猜测是构建器任务无法理解要在 app.module 中使用的模拟 class 中的条件导出。

So this forced me to use both classes in the app-init and other class I use it and check for the environment mode in every one.所以这迫使我在 app-init 和其他 class 中使用这两个类,我使用它并检查每个类的环境模式。 I think it would be a much better solution if I could use only one class to treat this and just import it in all places I need.我认为如果我可以只使用一个 class 来处理它并将其导入到我需要的所有地方,那将是一个更好的解决方案。

this is my build command:这是我的构建命令:

ng build --prod=true --configuration=production --delete-output-path --output-path=dist/

How can I overcome this error in the build?如何克服构建中的这个错误? Also... why on earth all works well in dev mode and the build behaves differently?另外......为什么在开发模式下一切都运行良好并且构建行为不同?

I guess you're using Angular 8 or less.我猜你正在使用 Angular 8 或更少。

AOT compiler in those versions doesn't support resolving reference to default export.这些版本中的 AOT 编译器不支持解析对默认导出的引用。

So you should be more specific:所以你应该更具体:

keycloak-mock.service.ts keycloak-mock.service.ts

const KeycloakServiceImpl =
  environment.production ? KeycloakService : MockKeycloakService;
export { KeycloakServiceImpl };

app.module.ts app.module.ts

import { KeycloakServiceImpl } from './keycloak-mock.service';

...
deps: [KeycloakServiceImpl]

Tip:小费:

ng build --prod is an equivalent of ng build --prod=true --configuration=production ng build --prod相当于ng build --prod=true --configuration=production

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM