fromdeno / deno2node

Compile your Deno project to run on Node.js.
MIT License
117 stars 3 forks source link

TS2307: Cannot find module 'npm:third-part-dep' or its corresponding type declarations. #35

Closed MasterKale closed 1 year ago

MasterKale commented 1 year ago

I'm experimenting with refactoring a TypeScript Node library to make it isomorphic and hopefully work in Deno. I've been trying to figure out the best way to pull this off, and after finding deno2node I've decided to try making my library Deno-first and use deno2node to generate a Node-compatible version.

Unfortunately after getting the library working in Deno, deno2node errors out because the npm packages all have "npm:" in front of them which what appears to be a run of tsc after emitting files doesn't like:

npx deno2node
Loading tsconfig: 606.956ms
Basic transformations: 119.971ms
Vendoring: 0.593ms
Shimming: 0.322ms
Emitting: 1.915s
src/authentication/generateAuthenticationOptions.ts:6:8 - error TS2307: Cannot find module 
'npm:@simplewebauthn/typescript-types' or its corresponding type declarations.

6 } from 'npm:@simplewebauthn/typescript-types';
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

...snip...

TypeScript 4.8.2
Found 71 errors.

Do you have a suggestion for how best to handle this? I was reading the section of the README about "Runtime-specific code" and wondering if I need to maintain a "deps.deno.ts" and a "deps.node.ts" to each import third-party libraries using Deno- and Node-specific naming conventions. It's not an ideal solution, though, from a developer experience perspective.

Alternatively, do you have any plans/ability to add a step to all the things deno2node does that would automatically remove "npm:" from import paths if they exist?

KnorpelSenf commented 1 year ago

IMO it would make sense to just support npm: imports. Should be relatively easy to do.

You are correct that you can use run-time specific code to include different import statements per platform. That's usually how dependencies can be handled with d2n and it works for npm: imports, too.

wojpawlik commented 1 year ago

Versioned imports already work. https://github.com/fromdeno/deno2node/blob/28e03a6411f95129d477b514a3d458bb1508f067/src/_transformations/specifiers.ts#L10 https://github.com/fromdeno/deno2node/blob/28e03a6411f95129d477b514a3d458bb1508f067/src/_transformations/specifiers.ts#L3-L4 would need to be changed to support unversioned imports. Which shouldn't be used anyway.

wojpawlik commented 1 year ago

const scopedPackage = /(?:@[\w.-]+\/)?[\w.-]+/?

MasterKale commented 1 year ago

...would need to be changed to support unversioned imports. Which shouldn't be used anyway.

Oh, so if I added a version to these imports then deno2node would already handle this? Then maybe the answer here is, "learn to write Deno." I've been aware of Deno and its differences, including how it encourages (requires?) stricter dependency pinning. In this case I could see myself not going far enough with my refactor and needing to be more explicit with version tags on these.

But then again, as a library maintainer I'd want to not pin any dependencies so that consumers of my libraries would be able to get security updates for my dependencies...does Deno have an opinion about this? Can I use versions in my NPM Deno imports like I do in my package.json? 🤔

Edit: The Deno docs on npm usage immediately reference import express from "npm:express@^4.18"; so my last point is addressed.

wojpawlik commented 1 year ago

import express from "npm:express@^4.18"

Working on bringing this to deno2node tomorrow