josdejong / svelte-jsoneditor

A web-based tool to view, edit, format, repair, query, transform, and validate JSON
https://jsoneditoronline.org
Other
814 stars 108 forks source link

Angular 15 + Jest ESM issues #446

Closed cloakedninjas closed 3 weeks ago

cloakedninjas commented 3 weeks ago

Decided to upgrade from jsoneditor to vanilla-jsoneditor in our Angular app. All works well client-side but then the tests fail

SyntaxError: Cannot use import statement outside a module

      13 | } from '@angular/core';
      14 | import { ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
    > 15 | import { JSONEditor, Mode } from 'vanilla-jsoneditor';
         | ^

I was reading https://github.com/josdejong/svelte-jsoneditor/issues/334#issuecomment-1812023102 and tried to migrate our jest setup to use ESM, but that was a rabbit hole of issues with jest-preset-angular

Is providing a CommonJS build still a solution to this issue? And if so, would it be possible to add?

josdejong commented 3 weeks ago

It seems to me that Jest is the culprit here. The ESM related issues of Jest are open for 4.5 years now (!), they are even pinned to the issues section of the repo. I don't see any active work to make Jest work with ESM.

How about switching from Jest to Vitest? Vitest is compatible with Jest, and works out of the box with ESM and TS and everything.

cloakedninjas commented 3 weeks ago

Sure I might look at Vitest if I get some time, perhaps it's a drop-in replacement, but reading https://github.com/angular/angular-cli/issues/25217 there are some good points raised. Jest is the defacto standard and I think it'll be in the web ecosystem for many years to come.

For my particular issue I managed to bypass the issue by supplying a shim in jest.config.js

moduleNameMapper: {
  ...
  'vanilla-jsoneditor': 'shim-vanilla-jsoneditor.ts'
}

With the following minimal class to satisfy Angular's lifecycle hook:

export class JSONEditor {
    destroy() {
        //
    }
}

None of our unit tests actually interact with the editor, so this might not work for everyone. But from Jest's perspective our <json-editor> is just a plain HTML element instead of an Angular component

josdejong commented 3 weeks ago

Good to hear you've found a working solution! Thanks for sharing it.

Jest is the defacto standard and I think it'll be in the web ecosystem for many years to come.

I'm afraid so. I guess it depends in large part on choices being made by a handful of "big guys" like Angular and the now deprecated create-react-app on whether or not to keep shiping Jest as the default (or only) test runner. It somehow doesn't feel right to me to ask all library publishers to keep shipping old-style CommonJS because one library, Jest, still doesn't have good support for modern ESM. ESM is there now for 8 or 9 years or so, and it is not a small, insignificant feature we're talking about: the module system is at the heart of JavaScript. Isn't it time to move on?

I personally have used Jest in quite some projects, but always had trouble to get it set up correctly in combination with TS and ESM. Nowadays I'm using Vitest a lot and that is such a relief: it just works.