Open marvinhagemeister opened 1 year ago
Thanks for creating this. I already wanted to do this, but sadly wasn't able to get it working. (Even with your hints here!) I tried using flowbite, after seeing this conversation: https://github.com/denoland/fresh/discussions/1363.
Are you saying that it's not possible to do this as server rendered components? This stuff will only work as islands?
FYI: Just fixed that for a discord user for radix-ui
with the following changes: https://github.com/hapaxlife/test-fresh-radix-ui/pull/1/files
I try to use https://floating-ui.com/docs/react. But ESBUILD always complaint:
✘ [ERROR] Module not found "https://esm.sh/@floating-ui/react@0.25.4?external=react,react-dom,react/jsx-runtime". [plugin deno-loader]
uuid.tsx:3:28:
3 │ import { useFloating } from "@floating-ui/react";
╵ ~~~~~~~~~~~~~~~~~~~~
error: Uncaught (in promise) Error: Build failed with 1 error:
uuid.tsx:3:28: ERROR: [plugin: deno-loader] Module not found "https://esm.sh/@floating-ui/react@0.25.4?external=react,react-dom,react/jsx-runtime".
let error = new Error(text);
^
at failureErrorWithLog (https://deno.land/x/esbuild@v0.19.2/mod.js:1625:15)
at https://deno.land/x/esbuild@v0.19.2/mod.js:1034:25
at runOnEndCallbacks (https://deno.land/x/esbuild@v0.19.2/mod.js:1460:45)
at buildResponseToResult (https://deno.land/x/esbuild@v0.19.2/mod.js:1032:7)
at https://deno.land/x/esbuild@v0.19.2/mod.js:1061:16
at responseCallbacks.<computed> (https://deno.land/x/esbuild@v0.19.2/mod.js:679:9)
at handleIncomingPacket (https://deno.land/x/esbuild@v0.19.2/mod.js:738:9)
at readFromStdout (https://deno.land/x/esbuild@v0.19.2/mod.js:655:7)
at https://deno.land/x/esbuild@v0.19.2/mod.js:1923:11
at eventLoopTick (ext:core/01_core.js:183:11)
import_map
{
"imports": {
"react": "https://esm.sh/preact/compat",
"react-dom": "https://esm.sh/preact/compat",
"react/jsx-runtime": "https://esm.sh/preact/jsx-runtime",
"@floating-ui/react": "https://esm.sh/@floating-ui/react@0.25.4?external=react,react-dom,react/jsx-runtime"
}
}
Could you teach me how to use it in proper way?
@ynwd ah, looks like the slash in react/jsx-runtime
must be encoded for URLs.
{
"imports": {
"react": "https://esm.sh/preact/compat",
"react-dom": "https://esm.sh/preact/compat",
"react/jsx-runtime": "https://esm.sh/preact/jsx-runtime",
- "@floating-ui/react": "https://esm.sh/@floating-ui/react@0.25.4?external=react,react-dom,react/jsx-runtime"
+ "@floating-ui/react": "https://esm.sh/@floating-ui/react@0.25.4?external=react,react-dom,react%2Fjsx-runtime"
}
}
Thanks @marvinhagemeister .
The error completely disappeared after I set import_map like this:
"imports": {
"react": "https://esm.sh/preact@10.17.1/compat",
"react-dom": "https://esm.sh/preact@10.17.1/compat",
"react/jsx-runtime": "https://esm.sh/preact@10.17.1/jsx-runtime",
"preact": "https://esm.sh/preact@10.17.1",
"preact/": "https://esm.sh/preact@10.17.1/",
"@floating-ui/react": "https://esm.sh/@floating-ui/react@0.25.4?alias=react:preact/compat,react-dom:preact/compat,@types/react:preact/compat&deps=react"
}
and add configPath
at esbuild deno-plugins:
plugins: [
...denoPlugins({
configPath,
}),
]
@ynwd Why was the configPath
argument needed?
The aliasing works too, although it's a bit more verbose than marking modules as external.
@ynwd Why was the
configPath
argument needed?The aliasing works too, although it's a bit more verbose than marking modules as external.
The plugin requires it to read from the deno.json
path.
Is there a risk that the suggested approach will cause problems by introducing duplicate versions of Preact? I think you might have to be careful to include the same version specifier in the https://esm.sh URLs of 5 different import map entries - "preact", "preact/", "react", "react-dom" & "react/jsx-runtime".
I've been using an approach similar to @ynwd above - aliasing the react dependencies using the alias
query parameter, and using the external
query parameter to ensure the same preact
version/source is used throughout the application.
I've also had to be careful to specify an "es" target, otherwise the components may include Deno-specific code and fail in islands.
"<react-library>": "https://esm.sh/<react-library>?alias=react:preact/compat,react-dom:preact/compat,@types/react:preact/compat&external=preact&target=es2022",
It's unpleasantly verbose, but it's working well for several different packages.
React dependencies are hard to avoid, and I found it very difficult to work out how to do this, so documentation would be extremely useful. It's a shame that there's no aliasing support (yet?) using npm:
specifiers, as that might be easier.
@marvinhagemeister are you sure about the "only to be used inside an island" caveat? I've been rendering some components imported this way on the server with no problems. Might it depend on the specific package/component?
@adamgreg yeah depends on the package.
With Fresh 2.0 being published in jsr, the approach of aliasing react using esm.sh ?external=react no longer works (old approach example: https://github.com/shanipribadi/spikepreact), due to fresh depending on npm:preact and jsr import can't be mixed with esm.sh import.
but unfortunately, since deno does not support doing npm package aliasing yet https://github.com/denoland/deno/issues/18191, it's not possible to do so with only deno.
Instead I've figured out a way to make fresh 2.0 works with react using node-modules-dir manual and bun.
Following is the setup (using deno 2.0.4 and bun 1.1.33)
deno.json
"imports": {
"fresh": "jsr:@fresh/core@^2.0.0-alpha.24",
"@fresh/plugin-tailwind": "jsr:@fresh/plugin-tailwind@^0.0.1-alpha.7",
"preact/jsx-runtime": "npm:preact@^10.24.3/jsx-runtime"
},
all jsr dependencies added to deno.json imports, with the occassional import-map mapping as required (e.g. preact/jsx-runtime imported by fresh)
package.json
"nodeModulesDir": "manual",
"dependencies": {
"@coreui/react": "npm:@coreui/react@^5.4.1",
"@preact/signals": "npm:@preact/signals@^1.3.0",
"esbuild": "npm:esbuild@0.23.1",
"esbuild-wasm": "npm:esbuild-wasm@0.23.1",
"preact": "npm:preact@^10.24.3",
"preact-render-to-string": "npm:preact-render-to-string@^6.5.11",
"react": "npm:@preact/compat@^18.3.1",
"react-dom": "npm:@preact/compat@^18.3.1"
}
all npm dependencies added to package.json to be managed by bun, including transitive npm dependencies of the jsr dependencies. react and react-dom is aliased by bun by configuring it in package.json.
bun install
deno task dev
Note: not all react npm components work this way, coreui does work because it seemed they published an esm module, but react-insta-stories didn't work because of https://github.com/preactjs/preact/issues/2690, I assumed because they're not publishing esm module, and the webpack require caused a duplicate preact import.
A working repository example is provided here: https://github.com/shanipribadi/spikefreshreact The repo has a working CoreUI Button both in an islands and in a SSR context.
Preact has a React compatibility layer with which most React-based component libraries can be used with Preact. Document how this can be set up in fresh.
Aliases are not supported with
npm:
so far, but work with esm.sh when setting them in the import map:Once set up, there is the caveat that those can only be used inside an island as they need client side JS to run