简体   繁体   中英

Angular, Nx Workspace, Webpack 5 Module Federation: You provided an invalid object where a stream was expected

I am currently working on a project that uses Webpack 5's Module Federation. The project contains to Angular 12 applications: one application is the shell and the other one is the remote that should be loaded into the shell. Both apps are running perfectly fine on their own but the following error occurs when importing the remote into the shell application:

core.js:6479 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at subscribeTo (subscribeTo.js:27)
    at innerSubscribe (innerSubscribe.js:71)
    at MergeMapSubscriber._innerSub (mergeMap.js:57)
    at MergeMapSubscriber._tryNext (mergeMap.js:51)
    at MergeMapSubscriber._next (mergeMap.js:34)
    at MergeMapSubscriber.next (Subscriber.js:49)
    at Observable._subscribe (subscribeToArray.js:3)
    at Observable._trySubscribe (Observable.js:42)
    at Observable.subscribe (Observable.js:28)
    at MergeMapOperator.call (mergeMap.js:19)

The remote application is starting requests to both a REST- and a GraphQL-interface. It seems the error occurs when the requests are executed and observables are returned. My guess is that something with my dependencies is causing the problem. Those are the dependencies I have currently installed:

{
    "@angular-architects/module-federation": "^12.4.0",
    "@angular/animations": "^12.0.0",
    "@angular/cdk": "^12.1.3",
    "@angular/common": "^12.0.0",
    "@angular/compiler": "^12.0.0",
    "@angular/core": "^12.0.0",
    "@angular/forms": "^12.0.0",
    "@angular/material": "^12.1.3",
    "@angular/platform-browser": "^12.0.0",
    "@angular/platform-browser-dynamic": "^12.0.0",
    "@angular/router": "^12.0.0",
    "@apollo/client": "^3.3.21",
    "@ngx-translate/core": "^13.0.0",
    "@ngx-translate/http-loader": "^6.0.0",
    "@nrwl/angular": "^12.5.8",
    "ag-grid-community": "^25.3.0",
    "apollo-angular": "^2.6.0",
    "bootstrap": "^5.0.2",
    "flag-icon-css": "^3.5.0",
    "graphql": "^15.5.1",
    "graphql-tag": "^2.12.5",
    "ngx-toastr": "^14.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.11.4"
}

I also tried adjusting the Webpack-configuration, but the changes didn't help. The shell and remote application share the following libraries through Module Federation:

{
    '@angular/cdk': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@angular/core': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@angular/common': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@angular/common/http': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@angular/router': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@angular/material': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@angular/forms': { singleton: true, strictVersion: true, requiredVersion: '12.1.3' },
    '@libs/storage-client': { singleton: true },
    ...sharedMappings.getDescriptors()
}

The full stacktrace looks as follows:

core.js:6479 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at subscribeTo (subscribeTo.js:27)
    at innerSubscribe (innerSubscribe.js:71)
    at MergeMapSubscriber._innerSub (mergeMap.js:57)
    at MergeMapSubscriber._tryNext (mergeMap.js:51)
    at MergeMapSubscriber._next (mergeMap.js:34)
    at MergeMapSubscriber.next (Subscriber.js:49)
    at Observable._subscribe (subscribeToArray.js:3)
    at Observable._trySubscribe (Observable.js:42)
    at Observable.subscribe (Observable.js:28)
    at MergeMapOperator.call (mergeMap.js:19)
defaultErrorLogger  @   core.js:6479
handleError @   core.js:6527
next    @   core.js:29316
__tryOrUnsub    @   Subscriber.js:183
next    @   Subscriber.js:122
_next   @   Subscriber.js:72
next    @   Subscriber.js:49
next    @   Subject.js:39
emit    @   core.js:25968
(anonymous) @   core.js:28731
invoke  @   zone.js:372
run @   zone.js:134
runOutsideAngular   @   core.js:28604
onHandleError   @   core.js:28731
handleError @   zone.js:376
runTask @   zone.js:181
invokeTask  @   zone.js:487
ZoneTask.invoke @   zone.js:476
data.args.<computed>    @   zone.js:2541
setTimeout (async)      
scheduleTask    @   zone.js:2543
scheduleTask    @   zone.js:393
onScheduleTask  @   zone.js:283
scheduleTask    @   zone.js:386
scheduleTask    @   zone.js:221
scheduleMacroTask   @   zone.js:244
scheduleMacroTaskWithCurrentZone    @   zone.js:679
(anonymous) @   zone.js:2585
proto.<computed>    @   zone.js:975
hostReportError @   hostReportError.js:2
error   @   Subscriber.js:156
_error  @   Subscriber.js:75
error   @   Subscriber.js:55
notifyError @   innerSubscribe.js:45
_error  @   innerSubscribe.js:13
error   @   Subscriber.js:55
notifyError @   innerSubscribe.js:45
_error  @   innerSubscribe.js:13
error   @   Subscriber.js:55
innerSubscribe  @   innerSubscribe.js:74
_innerSub   @   mergeMap.js:57
_tryNext    @   mergeMap.js:51
_next   @   mergeMap.js:34
next    @   Subscriber.js:49
(anonymous) @   subscribeToArray.js:3
_trySubscribe   @   Observable.js:42
subscribe   @   Observable.js:28
call    @   mergeMap.js:19
subscribe   @   Observable.js:23
innerSubscribe  @   innerSubscribe.js:67
call    @   takeUntil.js:11
subscribe   @   Observable.js:23
_resetOptions   @   select.js:748
(anonymous) @   select.js:421
__tryOrUnsub    @   Subscriber.js:183
next    @   Subscriber.js:122
_next   @   Subscriber.js:72
next    @   Subscriber.js:49
_next   @   Subscriber.js:72
next    @   Subscriber.js:49
notifyNext  @   mergeMap.js:70
_next   @   innerSubscribe.js:10
next    @   Subscriber.js:49
(anonymous) @   subscribeToArray.js:3
innerSubscribe  @   innerSubscribe.js:71
_innerSub   @   mergeMap.js:57
_tryNext    @   mergeMap.js:51
_next   @   mergeMap.js:34
next    @   Subscriber.js:49
(anonymous) @   subscribeToArray.js:3
_trySubscribe   @   Observable.js:42
subscribe   @   Observable.js:28
call    @   mergeMap.js:19
subscribe   @   Observable.js:23
call    @   takeUntil.js:14
subscribe   @   Observable.js:23
ngAfterContentInit  @   select.js:420
callHook    @   core.js:2526
callHooks   @   core.js:2495
executeInitAndCheckHooks    @   core.js:2446
refreshView @   core.js:9505
refreshEmbeddedViews    @   core.js:10589
refreshView @   core.js:9488
refreshComponent    @   core.js:10635
refreshChildComponents  @   core.js:9261
refreshView @   core.js:9514
refreshEmbeddedViews    @   core.js:10589
refreshView @   core.js:9488
refreshComponent    @   core.js:10635
refreshChildComponents  @   core.js:9261
refreshView @   core.js:9514
renderComponentOrTemplate   @   core.js:9578
tickRootContext @   core.js:10809
detectChangesInRootView @   core.js:10834
detectChanges   @   core.js:22887
tick    @   core.js:29711
(anonymous) @   core.js:29571
invoke  @   zone.js:372
onInvoke    @   core.js:28705
invoke  @   zone.js:371
run @   zone.js:134
run @   core.js:28559
next    @   core.js:29570
__tryOrUnsub    @   Subscriber.js:183
next    @   Subscriber.js:122
_next   @   Subscriber.js:72
next    @   Subscriber.js:49
next    @   Subject.js:39
emit    @   core.js:25968
checkStable @   core.js:28627
onLeave @   core.js:28755
onInvokeTask    @   core.js:28699
invokeTask  @   zone.js:405
runTask @   zone.js:178
invokeTask  @   zone.js:487
invokeTask  @   zone.js:1600
globalZoneAwareCallback @   zone.js:1626

The error occurs when subscribing to an observable that was returned by a method:

this.getAllSeries().subscribe(allSeries => {
    // This is where the error occurs
}

Those are the functions that are called:

public getAllSeries(): Observable<Filter[]> {
    const requestParameters: RequestParameters = {
        url: `${this.storageBaseUrl}/filters?type=series`,
        headers: {
            Authorization: this.authorizationToken
        },
        responseType: "json"
    };
    return this.requestService.getRequest<Filter[]>(requestParameters);
}

public getRequest<T>(request: RequestParameters, withAuth: boolean = true): Observable<T> {
    return this.http
        .get<T>(request.url, {
            headers: request.headers,
            responseType: request.responseType === "arraybuffer" || request.responseType === "blob"
                ? (request.responseType as "json")
                : "json"
        })
        .pipe(take(1));
}

I just found the problem myself. It seems that because of the usage of Module Federation the type Observable couldn't be referenced in the micro-frontend. I had to add rxjs and rxjs/operators to the shared libraries in the Webpack configuration file. Both the shell and remote application now share these libraries:

{
    '@angular/cdk': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    '@angular/core': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    '@angular/common': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    '@angular/common/http': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    '@angular/router': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    '@angular/material': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    '@angular/forms': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    'rxjs': { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    'rxjs/operators': { singleton: true, strictVersion: true, requiredVersion: '~6.6.0' },
    '@libs/storage-client': { singleton: true },
    ...sharedMappings.getDescriptors()
}

I was also able to remove the fixed version numbers for the shared libraries. It only is necessary for rxjs/operators because it isn't an extra npm module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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