Skip to content

RxJS v6 testing breaking with ESBuild bundling (Jest testing) #25405

Closed
@devversion

Description

@devversion

Command

test

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

main

Description

Currently, using a builder that leverages ESBuild under the hood. e.g. the Jest builder- results in runtime breakages when RxJS v6 is used together with the TestScheduler code.

  it('should work', () => {
    new TestScheduler((a, b) => expect(a).toEqual(b)).run(({cold, expectObservable}) => {
      expectObservable(cold('-t', {t: 'hi'})).toBe('-t', {t: 'hi'});
    });
  });

Root cause:

RxJS v6 does not have exports conditions, so the mainFields will be respected. The ESBuild code path
does not match the ES2015+ main fields, but instead matches just module- causing the ES5 distribution
to be bundled. This ends up breaking at runtime. If the es2015 main field would have matched- no error
would have occurred.

This seems to happen because, the ES5 distribution applies mixins for the ColdObservable class using a @PURE side-effect call, while in ES2015 it's not marked as side-effect free.

ES5 (breaking)
image

ES2015
image

Minimal Reproduction

https://github.com/devversion/rxjs-v6-esbuild-cli-breaking

Exception or Error

● AppComponent › should work

    expect(received).toEqual(expected) // deep equality

    - Expected  - 5
    + Received  + 5

      Array [
        Object {
    -     "frame": 1,
    +     "frame": 0,
          "notification": Notification2 {
    -       "error": undefined,
    -       "hasValue": true,
    -       "kind": "N",
    -       "value": "hi",
    +       "error": [TypeError: observable.logSubscribedFrame is not a function],
    +       "hasValue": false,
    +       "kind": "E",
    +       "value": undefined,
          },
        },
      ]

      at TestScheduler2.TestScheduler.run.cold.cold [as assertDeepEqual] (src/app/app.component.spec.ts:35:43)
      at node_modules/rxjs/_esm5/internal/testing/TestScheduler.js:122:23
          at Array.filter (<anonymous>)
      at TestScheduler2.flush (node_modules/rxjs/_esm5/internal/testing/TestScheduler.js:120:43)
      at TestScheduler2.run (node_modules/rxjs/_esm5/internal/testing/TestScheduler.js:346:18)
      at src/app/app.component.spec.ts:35:55
      at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:368:26)
      at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:273:39)
      at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:367:52)
      at _Zone.run (node_modules/zone.js/fesm2015/zone.js:129:43)
      at Object.wrappedFunc (node_modules/zone.js/fesm2015/zone-testing.js:740:30)


### Your Environment

```text
Angular CLI: 16.1.0
Node: 16.14.2
Package Manager: npm 8.19.2
OS: linux x64

Angular: 16.1.1
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1601.0
@angular-devkit/build-angular   16.1.0
@angular-devkit/core            16.1.0
@angular-devkit/schematics      16.1.0
@angular/cli                    16.1.0
@schematics/angular             16.1.0
rxjs                            6.6.7
typescript                      5.1.3

Anything else relevant?

Possible solutions:

  • For RxJS v6, we should add es2015 as condition.
  • We should consider not optimizing when bundling for tests?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions