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

possible to not require ESM ? #11

Open
dcsan opened this issue Jul 24, 2022 · 10 comments
Open

possible to not require ESM ? #11

dcsan opened this issue Jul 24, 2022 · 10 comments

Comments

@dcsan
Copy link

dcsan commented Jul 24, 2022

I have a huge project and always hit problems trying to use "pure" ESM. Mainly because I'm using typescript, which just doesn't seem to work well with ESM...

I know the node-fetch guys want to force ESM but the older versions "node-fetch": "2.6.1", work fine.

one thing that would be nice for this package is proper type definitions, which you get for free if you wrote it in typescript?

any thoughts?

I've been wading thru my project for an hour already and have another Found 967 errors in 262 files. ... to do with various import problems. some other broken packages eg sequelize-typescript use TS meta magic that's out of my depth to fix, at which point I gave up.

For importing raw binary data eg from the Dalle-min model I found the node-fetch library did a good job. I was planning to throw it out and use axios or another lib, but found it easier to just use node-fetch older version.

@dcsan
Copy link
Author

dcsan commented Jul 24, 2022

@nicholascelestin
Copy link
Owner

Hey @dcsan , thanks for taking the time to post some feedback!

I do agree that Typescript would offer a better development experience for maintainers and consumers of the library. But, I've put off Typescript because it requires additional build and test tooling, which feels like overkill for ~100 lines of code. And it has some implications for the portability of the library. And I'm no Typescript expert.

Do you think that JSDoc typing information for public methods might be a good first step to improve the development experience for consumers of the library? Here's an article that summarizes how that works and that mostly aligns with my opinion: https://blog.logrocket.com/typescript-vs-jsdoc-javascript/.

But the bigger issue is this library clashing with Typescript's support for ESM. What version of Typescript does your project use? And is there anything that is preventing you from using TypeScript 4.7+?

@dcsan
Copy link
Author

dcsan commented Jul 27, 2022

tx for the response! and the nice and understandable code base!

i found typescript makes it easy to build packages when i've used it, and then you have a typings file created too. One thing I hit right away on using this plugin was a "no typings" warning, and I guess none exist. So I had to wrap all calls with : any which isn't great for a library where you don't know the types.

i understand the risk is it might put off people contributing, but if you set everything up, it's not a big deal to just edit / build.

JSDoc is a bit of a band-aid approach imho. It's always half worked for me and depends on the editor having the right intellisense plugins installed. using typescript would fix this properly.

yes, the bigger issue is as soon as I add type: module to the project I have to update 100s of files.
there are some nasty things, like
https://2ality.com/2021/06/typescript-esm-nodejs.html#typescript

all imports now need to have .js - even for typescript files

typescript by default always uses import { x} from "package" syntax anyway so I'm not sure that the purist ESM approach adds anything, but boy does it require a lot of changes. I spent a few hours to get to this point:
image

some of the problems created in dependent libraries are more baffling:
sequelize/sequelize-typescript#1369

so if it was possible to switch to 2.6 of node-fetch or use axios or a less requiring of going cold turkey ESM to do requests it would be easier to adopt this package into a typescript app.

I did actually try axios but had some problems with unpacking the binary data, so just switched to an older node-fetch. It's probably something we could figure out.

@vastamaki
Copy link
Collaborator

I believe we can use node-fetch@2, or switch to axios/cross-fetch. What do you think @nicholascelestin?

@nicholascelestin
Copy link
Owner

Sorry for the late response to this @dcsan -- I do appreciate the effort you put into your response. I just moved and that took up a lot of bandwidth for a couple of weeks.

Hmmm, are you saying that installing an older version of node fetch fixed the problem and that you didn't need to make any changes to the library itself in order to get it to work? And @vastamaki, is that what you're suggesting as well? If so, a quick way to resolve this issue (ahead of a full-on typescript rewrite) might be to add that proviso to the readme.

My limited understanding of ESM in modern Typescript (4.7+) is that there is interoperability such that you don't need to modify your whole project to use pure ESM. I think you can configure your compiler options like this: https://www.typescriptlang.org/docs/handbook/esm-node.html#type-in-packagejson-and-new-extensions
And use an import syntax like this (pulled from link above): import { helper } from "./foo.js"; // works in ESM & CJS

But I'm not 100%. Could you provide a bit of code that reproduces the issue you're having, so I can learn some about TS, fiddle with it, and see what's up?

@dcsan
Copy link
Author

dcsan commented Aug 8, 2022

are you saying that installing an older version of node fetch fixed the problem

not quite. the older versions of fetch I have used on other projects, as it didn't require porting everything to ESM. I didn't try to use that version with your package as yet.

I think you can configure your compiler options

yes I started on that process, but hit various snags, such as in other dependent libraries like sequelize-typescript. there really is no benefit to ESM i can see if you're already using typescript, and a LOT of problems and refactoring is required. also adding a clunky .js to all imports feels weird.

@blaynem
Copy link

blaynem commented Dec 10, 2022

Please add something. I've been banging my head against this for hours lol.

Edit:
Ended up just recreating everything from the API itself rather than try to go this route.

@dcsan
Copy link
Author

dcsan commented Jan 6, 2023

I think there's another package for replicate that isn't ESM based, you could ask in the discord.

@vastamaki
Copy link
Collaborator

Since NodeJS 18.13.0 is now LTS, supported by AWS and other major cloud platforms, and has a built-in fetch module, I believe we could use that instead of node-fetch in case the node version is >=18. I believe that would make things a bit simpler at least when using the latest NodeJS versions.

@archasek
Copy link

archasek commented Feb 5, 2023

UPDATE:

**Fixed! Solution:

  1. Use tsx instead of ts-node / ts-node-dev / nodemon.

  2. tsconfig.json:

"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
  1. package.json
    "type": "module"

  2. Run using tsx watch src/app.ts

Ref: zebreus/replicate-api#1**

--
ORIGINAL POST:

Hey guys, same problems here :). Any ideas how to overcome? I think I tried everything...

  • running nodemon --exec node --loader ts-node/esm src/app.ts
  • node v18
  • ts-node ver. 10.9.1, typescript ver. 4.9.5
  • package.json -> "type": "module"
  • tsconfig.json:
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,

I guess those settings are incorrect.

Before I tried to use the lib, my settings were like that (and the app was working ok):

  • running ts-node-dev --respawn src/app.ts
  • package.json -> no type at all
  • tsconfig.json:
"target": "esnext",
"module": "CommonJS"
"esModuleInterop": true,

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

5 participants