esm.sh icon indicating copy to clipboard operation
esm.sh copied to clipboard

Failed to import - react-dom

Open KyleJune opened this issue 2 years ago • 15 comments

Failing module

  • npm: https://www.npmjs.com/package/react-dom
  • https://www.npmjs.com/package/@types/react-dom
export { renderToReadableStream } from "https://esm.sh/[email protected]/server.browser?target=deno&pin=v78&[email protected]";

Error message

After running deno run I got this:

error: TS2305 [ERROR]: Module '"deno:///missing_dependency.d.ts"' has no exported member 'renderToReadableStream'.
export { renderToReadableStream } from "https://esm.sh/[email protected]/server.browser?target=deno&pin=v78&[email protected]";
         ~~~~~~~~~~~~~~~~~~~~~~
    at file:///home/kyle/Projects/deno/udibo/server_deps.ts:24:10

The issue appears to be that the types being included with it are wrong. If I go to the url in the browser, it shows the type url as x-typescript-types: https://cdn.esm.sh/v78/@types/[email protected]/server.browser~.d.ts which pins version 18.0.3 when I am trying to pin 18.1.0.

Additional info

  • esm.sh version: v78
  • Deno version: 1.21.1

My ci was importing the file with v77 successfully 3 days ago. Then today it failed even though my import line didn't change. After the failure, I tried pinning v78 but had the same issue. I believe what did change was the types header returned from esm.sh. If I force the type back from 18.0.3 to 18.0.2, it works. I'm not sure why react-dom types version doesn't match the current release version. It looks like esm just tries to use the latest in that case.

// @deno-types=https://cdn.esm.sh/v78/@types/[email protected]/server.browser~.d.ts
export { renderToReadableStream } from "https://esm.sh/[email protected]/server.browser?target=deno&pin=v78&[email protected]";

KyleJune avatar May 11 '22 04:05 KyleJune

@ije also hitting similar issues with these types myself, and was looking at whether there is a way to just pin types with esm.sh. Couldn't find it. My issue is that the types for react and the types for react included with the types for react-dom are mismatched.

jimisaacs avatar May 11 '22 14:05 jimisaacs

import { renderToReadableStream } from "https://esm.sh/[email protected]/server" just works, https://unpkg.com/browse/[email protected]/package.json check the 43 line, the latest update the server will resolve the export field correctly, server.browser doesn't have the types in face https://cdn.esm.sh/v78/@types/[email protected]/server.browser~.d.ts will returns empty types

ije avatar May 11 '22 14:05 ije

did everything just work itself out in the last 30 minutes? not getting any errors now.

jimisaacs avatar May 11 '22 15:05 jimisaacs

My issues went away in my private installation, seems the issue I described is still very much there on esm.sh. I suspect because of the cache. The architecture seems to rely on a new esm.sh version number every so often, as that would probably fix these kinds of things. Though in reality, if it's possible, it might be beneficial to control the cache in a little more fine-grained way, depending on hitting implicitly versioned urls and types, versus explicitly versioned ones.

jimisaacs avatar May 12 '22 12:05 jimisaacs

@ije should all unversioned urls always redirect?

jimisaacs avatar May 12 '22 12:05 jimisaacs

i.e. all urls without a full package version, excluding values in search url params, are always 307 redirected to a url with a full package version?

jimisaacs avatar May 12 '22 13:05 jimisaacs

yes, the version problem is painful, especially with react

ije avatar May 13 '22 05:05 ije

i plan to get rid of it, the idea is adding a stable channel

basiclly, we fix the stable channel to a specific build version, the unstable channel always point to the latest build version.

ije avatar May 13 '22 06:05 ije

when we updated the build version of the stable channel, we need to purge the cdn cache, but the client/deno need to reload/clean the cache, that's may a problem

ije avatar May 13 '22 06:05 ije

Although I actually like the idea of esm.sh build channels, because it gives a path to test changes, I actually think end users will probably never use it, because we already have the capability of pinning the build so it might actually be unnecessary in that regard? My reasoning is that users don't really care about esm.sh version, just the immutability or mutability of their package urls.

Also, to be honest, in the case of issues like this one, a stable channel might actually make things worse. The reason is because the actual problem here is with floating npm package versions, not floating the esm.sh build versions. A new esm.sh might actually fix all these issues. For example, what I think is going on is that there is a build of react types that gets cached in the browser and is associated with a floated react version url. I'm not sure if this will work or not, but I think handling this relationship with a redirect versus serving a JavaScript module that points to the right version might work better. We could lower the cache life of a redirect quite a bit, but keep the cache life of the destination pretty high, because it is a fully qualified version.

The second part of this issue here is the floating types versions. If I have react 18.1.0, and it wants @react/types, which is at the time version 18.0.8, what allows it to eventually get the newly published to npm @react/types 18.0.9? This is the actual issue I'm seeing between my private esm.sh installation versus the public one (no issue in my private installation because it's getting @types/react 18.0.9, while public esm.sh is still getting 18.0.8).

I don't actually see a way to ensure a 1-1 immutable association between packages and types in this architecture without adding yet another query parameter to manage types manually, which I'd really love to avoid...

So, let's lake a look at the issue at hand. Which is that older versions of types are getting cached with package urls. So would if implicitly associated types, were always floated in types headers? Even on fully qualified package urls. This way the floated types header would be what IDEs like VSCode and Deno reads, and then the hope is that they would follow a redirect to the latest qualified version of the types. So same idea as packages, but one step of indirection for the types through the header value.

As I was typing all that, I realize it would probably be prudent to try both things mentioned here. 1, try the floating types thing I described as the default behavior, 2, still implement yet another query param for types, which would probably be one of or something like these "?types=@types/react/18.0.9", "?types=18.0.9", "?types=18.0.x", "?check=@types/[email protected]", "?check=18.0.9", "?check=18", "?t=@types/[email protected]", "?t=18.0.9" etc..

jimisaacs avatar May 13 '22 11:05 jimisaacs

Regarding stable versus unstable channels. I don't think we'd need to purge the cdn cache on stable if stable just meant "pinned to build". So updating would just be pinning to a new build. Unless you mean somehow busting the cache of clients, I don't think we'd need to purge anything on the cdn itself right?

jimisaacs avatar May 13 '22 11:05 jimisaacs

quick followup, looks like "deno.land" uses redirects, i.e. https://deno.land/std/archive/tar.ts redirects to https://deno.land/[email protected]/archive/tar.ts, and it works with deno and vscode Screen Shot 2022-05-13 at 5 39 56 PM .

jimisaacs avatar May 13 '22 21:05 jimisaacs

This is the issue I have been describing in my previous messages https://github.com/esm-dev/esm.sh/issues/331

jimisaacs avatar May 17 '22 14:05 jimisaacs

import { renderToReadableStream } from "https://esm.sh/[email protected]/server" just works, https://unpkg.com/browse/[email protected]/package.json check the 43 line, the latest update the server will resolve the export field correctly, server.browser doesn't have the types in face https://cdn.esm.sh/v78/@types/[email protected]/server.browser~.d.ts will returns empty types

I believe I originally switched to using browser because the type was there but wasn't on server. When I switched to using server like you said, it worked. But now my CI is failing again saying it doesn't exist. So I'm guessing the version cached locally on my machine is good but currently broken if I were to refresh cache.

export { renderToReadableStream } from "https://esm.sh/[email protected]/server?target=deno&pin=v78&[email protected]";
error: TS2305 [ERROR]: Module '"deno:///missing_dependency.d.ts"' has no exported member 'renderToReadableStream'.
export { renderToReadableStream } from "https://esm.sh/[email protected]/server?target=deno&pin=v78&[email protected]";
         ~~~~~~~~~~~~~~~~~~~~~~
    at file:///home/runner/work/udibo/udibo/server_deps.ts:24:10

I checked the x-typescript-types header and it is set to "https://esm.sh/v78/@types/react-dom@^18/X-ZC9yZWFjdEAxOC4xLjA/server~.d.ts". If I go to that, it appears to be trying to import a version of react types pinned to v83 instead of v78 like I was pinning to.

import { ReactElement, ReactNode } from 'https://esm.sh/v83/@types/[email protected]/X-ZC9yZWFjdEAxOC4xLjA/index.d.ts';

I found I can fix it by changing deno-types. I think the ^18 version for react-dom is causing this new issue.

// @deno-types=https://esm.sh/v78/@types/[email protected]/X-ZC9yZWFjdEAxOC4xLjA/server~.d.ts
export { renderToReadableStream } from "https://esm.sh/[email protected]/server?target=deno&pin=v78&[email protected]";

KyleJune avatar May 30 '22 16:05 KyleJune

the redirect of https://esm.sh/v78/@types/react-dom@%5E18/X-ZC9yZWFjdEAxOC4xLjA/server~.d.ts is not right, i will fix it

ije avatar May 31 '22 05:05 ije

close this since we already added stable build channel for react

ije avatar Mar 23 '23 12:03 ije