-
-
Notifications
You must be signed in to change notification settings - Fork 106
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
Error loading in Deno #301
Comments
It seems s bit surprising that this would fail in Deno, given the TypeScript itself is fine with resolving |
I haven't actually gone through the process yet of creating a package which dual supports both Deno and Node in the same codebase so I'm not totally sure but I think in this case if the files were all importing each other as Then next, when you transpile to an npm package then you would need to have the transpiler essentially change all of the imports from .ts to .js in the final version, I'm not sure if typescript does this automatically with the right flags or if there is another library that is needed... Worth noting is that going through So if I change my import in Deno from https://deno.land/x/yaml to https://esm.sh/yaml then it works, its just a bit of a sub-par experience going directly through deno land. |
Seems like this is a relevant upstream issue: microsoft/TypeScript#27481 Deno is being rather strange here, as changing the extensions in the source to
As I'd prefer not to include the built files in the source repo's development branch and keep the version tags in the main history, is there a way of making this work? Tbh, the sense I get from Deno is that they've gone out of their way to making cross-compatibility with other environments difficult for library developers. |
The easiest possible fix for now may just be to put a link on the main README.md to tell Deno users to use https://esm.sh/yaml instead of deno.land, because it seems like that would work. In that case its just converting the published npm package into a cdn cached esm module. And again, I haven't really done it yet and your project is big enough where its hard for me to just make a little PR and say "see here is how you do it". But it seems like if you make it for Deno and have all of the files in the original source form as Deno compatible code where you're importing the actual .ts files instead of the non-existant .js files then it would work for deno. Then when you're building for node you'd need a tool which essentially transpiles it all to js and alters the imports to point to the correct modules (now .js files), then pack that up push it to npm and then throw away all the intermediate build output. I see you're using a tool called Which appears to have the support for ts bundling maybe? You might also be able to use swc? I'm not sure exactly. I'll have to experiment with something smaller. Of course the ideal tool for this would be the typescript compiler Here, for example, is a classic comment in that thread: Which I believe is nearly every developers initial experience with ESM modules... its completely unintuitive but once you realize you have to add Contrast that with the experience of using Deno... Where the intuitive thing just works right away. And there's only one way to do it and you don't even need npm or a package manager, its just intuitive and easy. Yet it is definitely frustrating to also be compatible with nodejs... so one has to wonder who's fault that really is. As someone who's been using Deno and dealing with these cross-compatibility issues I'll just just say its my perception that the reason why these challenges are happening is less because of Deno and more because of Node... Of course node is ubiquitous but many of these challenges came because members of the community just went ahead and solved some issues which became a defacto standard. Or like in this case, the standard was made purely with JS in mind and TS was ignored. Also making modules for the filesystem that weren't compabile with the web was a hugely bad idea. In my opinion Deno is coming in after all of this chaos with the advantage of hindsight and they have been taking a more purposeful approach with a more intentioned and reasoned decision making process, erring on the side of whats better and more correct than what happens in node which is more like what will work right now. Deno is the attempt to atone for the sins of its forebearers. Adding an import in your typescript code to a file which doesn't even exist is an example of that. Where are the js files in your code? Why should you have to import .js files when all your files are .ts? Its weird. Its a very nodejs thing and we get accustomed to these janks but Deno has turned a number of these decisions over and it affects compatibility in difficult ways but mostly because the way it was done in nodejs is questionable. To really fix that problem in nodejs and typescript you have to essentially fix multiple foundational layers lower down in... in which case you end up with Deno! I'm not a Deno team member and have no financial incentives to praise Deno but in my opinion Deno is the future and the more we can move that way even with the pain of trying to deal with backwards compatibility with node it will be worth it in the long haul. I am basically considering node a legacy platform at this point and Deno is its next-gen beta. If you have solutions or feedback for the community of deno developers on how to more easily support cross-platform module development I think it would be very valuable for the community and would likely impact the future of web development. Thank you for your efforts! |
I've previously participated in some of the discussion at denoland/deno#9569, but as you also mention, the Deno approach seems to be to figure out what works best in isolation of the rest of the JS ecosystem. In this case, the mismatch actually has nothing to do with Node.js, but with TypeScript, and how Deno's loader for it differs from the one provided by Microsoft and used by everyone else. As I mentioned previously, I don't really use Deno myself at all. I've tried previously to make sure that my code is Deno-compatible, but I'm not going to make it less compatible with I would be willing to entertain a PR e.g. adding some note in the README and/or the docs site, but I continue to be sceptical about Deno's general lack of compatibility. |
Since I had to re-read this and figure it out again, I just want to leave a note here about the actual solution. Perhaps something like below would be a nice addition to the main readme? ESMIts possible to load export * as yaml from 'https://esm.sh/yaml@2.1.1'; |
Or actually pulling from esm.sh seems to have problems with the latest version of Deno so an alternative is this: import {
parse,
stringify,
} from "https://deno.land/std@0.152.0/encoding/yaml.ts";
export const YAML = { parse, stringify }; |
@justinmchase that's not the same library. This works just fine in Deno: import YAML from 'https://esm.sh/yaml@2.1.3'
const { parse, stringify } = YAML |
While ESM works, the module published on deno.land/x does not: import Yaml from "https://deno.land/x/yaml@v2.4.3/src/index.ts"
> Uncaught TypeError: Module not found "https://deno.land/x/yaml@v2.4.3/src/compose/composer.js".
at https://deno.land/x/yaml@v2.4.3/src/index.ts:1:26
at async <anonymous>:1:50 (It should be looking for |
import * as yaml from 'npm:yaml@2.4.3' Or better yet, deno add npm:yaml@2.4.3 Then just import yaml from 'yaml' Note that the standard library also already supports YAML, through deno add jsr:@std/yaml |
Okay, If that's the official usage then you might want to remove the deno module since its broken |
I would agree with the previous comment, what's published to deno.land/x I would expect to work with Deno as a Deno compatible module. |
PRs welcome for adding a separate Deno endpoint and build that renames the imports and adds tests verifying that the result works in Deno. |
Alright I made a generic tool for the renames using the tree-sitter parser. Haven't finished tayloring it to this codebase specifically, but I've got a hand-edited WIP branch over here to give you an idea of what the changes Look like. In addition to .js->.ts
but after that it seems to pass tests. I'm sure there's a way to do much of this with a deno.json, but I'm not a huge fan of deno.json |
These sound like changes that could/should at least in part be applied directly to the source, rather than layered on for Deno specifically. As in, please file a separate PR for these.
Is Jest not used as the test runner for the proposed Deno build? At least in Node.js, it's handling the path rewrites for the test imports. |
Great! Thats exactly what I was hoping to get some feedback on.
Yeah, I have no idea how this works. Both I didnt realize that was a feature of Jest, and I'm not sure how that Jest feature ends up interacting with Deno. Thanks for that link. Whenever I look at this again, that will help me figure out what's going on. |
Describe the bug
To Reproduce
Steps to reproduce the behaviour.
deno eval "export * as YAML from 'https://deno.land/x/yaml@v2.0.0-7/src/index.ts'"
Expected behaviour
I expect the module to be loaded successfully, no errors
Versions (please complete the following information):
yaml
:v2.0.0-7
Additional context
Full stack:
The files of course are all typescript in the repository and it fails trying to download them because in the code they're all referencing each other as
.js
. I believe in node it works because its running all the transpiled files after typescript gets them but in Deno that transformation is transparent and it requires the references to be correct.I know there are a couple of ways to solve this, such as using some auto-esm transpiler, or perhaps you have the JS version published somewhere that I'm not seeing... but I didn't see any documentation in your readme on the way you're intending it to be supported so I thought I'd ask here.
The text was updated successfully, but these errors were encountered: