Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to import jsonpatch - version 0.6.0 #356

Open
slubowsky opened this issue Dec 22, 2023 · 6 comments
Open

Unable to import jsonpatch - version 0.6.0 #356

slubowsky opened this issue Dec 22, 2023 · 6 comments

Comments

@slubowsky
Copy link

In typescript (angular) application had been patching version 0.5.0 to include missing jsonpatch in exported formatters and was importing like this:
import { DiffPatcher, formatters } from 'jsondiffpatch';
and all was good. (tsconfig has esModuleInterop set to true)

Now after update to 6.0 not sure how to import. Either of these seems to compile but crashes when try to run:

import { format, Op } from 'jsondiffpatch/lib/formatters/jsonpatch';
import * as jsonpatch from 'jsondiffpatch/lib/formatters/jsonpatch';

npm start
...
Application bundle generation complete. [3.149 seconds]
An unhandled exception occurred: Missing "./lib/formatters/jsonpatch" specifier in "jsondiffpatch" package
See "C:\Users\me\AppData\Local\Temp\ng-bKtu3M\angular-errors.log" for further details.
@Methuselah96
Copy link
Collaborator

Methuselah96 commented Dec 22, 2023

Hey @slubowsky, thanks for the issue!

What do you have "moduleResolution" set to in your tsconfig? For an Angular app, it should probably be set to "bundler" in order for TypeScript to use the "exports" field that's in jsondiffpatch's package.json.

If you have moduleResolution set correctly, you should be able to import it like this:

import * as jsonpatchFormatter from 'jsondiffpatch/formatters/jsonpatch';

Let me know if that helps!

@slubowsky
Copy link
Author

slubowsky commented Dec 22, 2023

@Methuselah96 I have it set to "node". Using current Angular 17.0.8 cli to generate a new app I see it sets it to "node" as well.
I tried to set it to bundler but my app fails to build... (new empty app does successfully build)

⠋ Building...
X [ERROR] Angular compilation initialization failed. [plugin angular-compiler]

  Error: Cannot resolve type entity i4.FocusTrapModule to symbol
      at reflectTypeEntityToDeclaration (file:///C:/...

@Methuselah96
Copy link
Collaborator

Yeah, sorry this is painful at the moment, but our hands are somewhat tied.

Problem

We can't support Node ESM without using package.json "exports", which means that users of the library need to configure their tools to read from package.json "exports", which most tools support by default.

TypeScript requires setting "moduleResolution" to "node16" or "bundler" in order to read package.json "exports". The TypeScript docs say that "moduleResolution": "node" should not be used for new projects and that only "node16"/"nodenext" or "bundler" should be used as the "moduleResolution" for new projects.

The reason the build is failing when you use "jsondiffpatch/lib/formatters/jsonpatch" is because Vite is also using the package.json "exports" field, and that path doesn't exist in the package.json "exports".

Ideal solution

For these reasons, Angular users should ideally have "moduleResolution" set to "bundler". There is an open Angular CLI issue to make that the new default.

What fails to build when you "moduleResolution" to "bundler"? If it's other npm packages maybe I can help contribute PRs to fix them so that they work with "moduleResolution": "bundler".

You'll want to switch to using "moduleResolution": "bundler" eventually, it's just a question of whether you're able to pull it off now.

Potential workaround

If your hands are tied, and you can't update "moduleResolution" to "bundler", you should be able to add a temporary declaration file to re-export the correct types from the right path. You should be able to create a jsondiffpatch.d.ts file anywhere inside the src directory with these contents:

declare module 'jsondiffpatch/formatters/jsonpatch' {
  export * from 'jsondiffpatch/lib/formatters/jsonpatch';
}

That should let TypeScript know that it can import from 'jsondiffpatch/formatters/jsonpatch' since it's not looking at the package.json "exports" field.

Let me know if that helps! Again, sorry for the friction, we're caught in the middle of the JS community slowly transitioning to using ESM by default, which can cause some pain if not everything supports it.

@slubowsky
Copy link
Author

Thanks for the detailed response! Ill try the potential workaround and see if it works. Ill update issue with results.

What fails to build when you "moduleResolution" to "bundler"? If it's other npm packages maybe I can help contribute PRs to fix them so that they work with "moduleResolution": "bundler".

Looks like its ngx-bootstrap. Error is Error: Cannot resolve type entity i4.FocusTrapModule to symbol and I find FocusTrapModule in their repo...
https://sourcegraph.com/github.com/valor-software/ngx-bootstrap/-/blob/src/focus-trap/focus-trap.module.ts?L14:14-14:29

@Methuselah96
Copy link
Collaborator

Methuselah96 commented Dec 22, 2023

Huh, I would not expect changing the "moduleResolution" to "bundler" to produce that error, since that seems like a build error coming from @ngtools\webpack and not a TypeScript error.

Maybe double-check that you're starting from a working build with a clean npm install and try changing "moduleResolution" to "bundler" from that state?

(Admittedly, I don't use Angular much, so I could be off-base in my understanding of that error.)

@slubowsky
Copy link
Author

Setting moduleResolution to Bundler fails even after clean install.
Build is not using webpack its using vite, I dont know if @ngtools\webpack still plays a role here. More complete error output is below:

npm run start-local

> app@0.0.840 start-local
> node --max-old-space-size=8192 ./node_modules/@angular/cli/bin/ng serve --hmr --configuration=development-local

⠧ Building...
X [ERROR] Angular compilation initialization failed. [plugin angular-compiler]

  Error: Cannot resolve type entity i4.FocusTrapModule to symbol
      at reflectTypeEntityToDeclaration (file:///C:/...

Good news is that declaration file workaround does work, so I dont need to worry about switching to Bundler for the moment...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants