
<h3>Question</h3>
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:
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.
This is the app.module I used:
<...>
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. 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.
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. 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.
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 ?
<h3>Answer1:</h3>
I guess you're using Angular 8 or less.
AOT compiler in those versions doesn't support resolving reference to default export.
So you should be more specific:
keycloak-mock.service.ts
const KeycloakServiceImpl =
environment.production ? KeycloakService : MockKeycloakService;
export { KeycloakServiceImpl };
app.module.ts
import { KeycloakServiceImpl } from './keycloak-mock.service';
...
deps: [KeycloakServiceImpl]
<em>Tip:</em>
ng build --prod
is an equivalent of ng build --prod=true --configuration=production
来源:https://stackoverflow.com/questions/62029756/how-can-i-use-a-class-that-use-conditional-export-in-angulars-app-module