-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Module resoultion in unpkg doesn't work. (Bug in unpkg) #2564
Comments
This seems to be more of an issue with the resolution algorithm of |
Nice, so Wouldn't it be so much nicer if you could tell people "here's how to install hooks", instead of "oh, use this specific cdn that implemented a particular resolution logic correctly". |
Preact's usage is a standard import statement, and also not really at the core of this issue, as I'll get to below. One point of clarification regarding // preact and preact/hooks: 10.3.x, and htm/preact: 3.x.x:
import { html, render } from 'https://npm.reversehttp.com/preact@10.3,preact@10.3/hooks,htm@3/preact'; Unpkg: the
|
Yes, the real issue is "how does preact/hooks get the correct preact instance so it can mess with the options" The solutions with For ES Modules to work in the browser as is, the imports must an absolute url or its a relative one. Just Neither the |
@Pyrolistical For ES Modules to work as is the library needs knowledge of the path it's hosted at. Let's say we host our app at the document root of a webserver (nginx, apache, etc). /webroot
/js
preact.module.js
hooks.module.js
index.html Relative URLs are immediately out of the picture as they are not based on the location of the js file, but the page that was served to the user. Let's say the user visited: So yeah, doesn't work. Next let's look at absolute URLs: For
Now what happens if the site is served from a sub-directory like For
Doesn't work either. So what can we do to resolve that? Current solutions
We could hardcode something like
To work around brittle import paths we could ship Preact with hardcoded import statements, like This works well for some users, but it's not possible for everyone to make a site depend on a third-party server. So that solution is a no go.
Like @developit outlined above a great solution for the time being is to rely on CDNs that can rewrite import paths like https://cdn.pika.dev, https://npm.reversehttp.com or others. Given your last comments it seems like this is not an option for you. At this point there aren't really other alternative solutions available, because there is a missing piece in ES Modules that hasn't been fleshed out yet. Future (hopefully)In essence we need something that makes import statements independent of the location the specified file was served from. Either something like on the server where we can say "resolve this import relative to the current file" or something that allows us to specify where import A should resolve to. The latter is usually referred to as "import maps", but it hasn't gotten much traction yet. In either way it's not something we can solve on Preact's end, it's a gap in the spec and it needs to be solved there to really make it work. Hopefully this will be tackled in the near future, as native ES Modules are finally gaining traction in real world usage. Until then bundlers or tools that can rewrite import paths are the only solution that works reliably for all web servers. Closing as this is an issue with the import spec and not with Preact. |
When I'm talking about relative path imports, I meant only for CDN, not self hosting. And I also meant only for the dependency like hooks. The top level import for preact would still be an absolute import. This way we would have // https://somecdn.com/preact@10.4.4/preact.js
...
export {options} // https://somecdn.com/preact@10.4.4/hooks.js
import {options} from './preact'
...
export {useState} // https://somewebsite.com/bundle.js
import {render} from 'https://somecdn.com/preact@10.4.4/preact.js'
import {useState} from 'https://somecdn.com/preact@10.4.4/hooks.js'
... This solves all the problems. No hardcoded third-party CDN url. Does not require CDNs that know how to rewrite. No npm assumption. Standard ES Module. The only tricky part of this is if you have a peer dep that is outside of the preact project, they wouldn't be able to get to the same preact instance unless they happen to use the same cdn. Now one could also argue this is a good thing as no third party module can now mess with preact unless the application passed the instance of preact to it. This would break stuff like preact-router which I'm looking at right now. |
Goal
I want to be able to use build websites with
preact
with modern ES Modules as a single index.html page, ie. no bundler.Problem
Right now the "browser" build of
preact/hooks
can be seen here: https://unpkg.com/preact@10.4.4/hooks/dist/hooks.module.jsThe problem is, its not browser compatible due to
import{options as n}from"preact";
Current solutions
Use
unpkg.com
with?module
First of all its a bundler, second of all it load its own un-versioned preact which wouldn't be the same preact I already loaded?
Use
npm.reversehttp.com
Again, another bundler and it also always loads the latest version making it hard to build a stable app.
Desired solution: Make
preact/hooks
pluggable intopreact
I like how
htm
andpreact
are independent ES Modules that can be wired together, as seen herehttps://twitter.com/pyrolistical/status/1266264165317935104
We can even continue to layer on a styled component library
If
preact
exposed an plugin system of some sort we could do the following:Why not just use a cdn bundler? I don't think this scales well into larger projects. When everything is welded together with a bundler, its harder get in there and customize.
And its non-standard! We don't need npm/commonjs anymore now that we have ES Modules.
The text was updated successfully, but these errors were encountered: