How to load islands in Fresh 2.0 plugins?

Im doing this one but looks like it's not working
import * as allIslands from './islands/mod.ts' // named export components

export function somePlugin<T>(
app: App<T>,
options: SomeOptions = {}
) {
app.use(someMiddleware(options))

const islandsUrl = new URL('./islands/mod.ts', import.meta.url);
for (const key of Object.keys(allIslands)) {
app.island(islandsUrl, key, allIslands[key])
}
}
import * as allIslands from './islands/mod.ts' // named export components

export function somePlugin<T>(
app: App<T>,
options: SomeOptions = {}
) {
app.use(someMiddleware(options))

const islandsUrl = new URL('./islands/mod.ts', import.meta.url);
for (const key of Object.keys(allIslands)) {
app.island(islandsUrl, key, allIslands[key])
}
}
7 Replies
marvinh.
marvinh.2mo ago
How are you using the islands? I can only see the setting up part in the snippet shared. That part seems correct when you say "not working" are you getting an error in the browser console? Are the islands rendered at all, just not interactive? Are the relevant JS files loaded in the network tabs in devtools? Are you using something external that minifes the HTML and that could potentially strip out HTML comments?
TheSadMidDeveloper
TheSadMidDeveloperOP2mo ago
Sorry I think I just ran the incorrect command haha. deno task start by default lol @marvinh. if it's okay to follow up regarding this one, if you look at the way Im installing plugins, the ./islands/mod.ts file there looks like this
export { default as SomeComponent } from './SomeComponent.tsx';
export * from './moreComponents.tsx';
export { default as SomeComponent2 } from './SomeComponent2.tsx';
export { default as SomeComponent3 } from './SomeComponent3.tsx';
export { default as SomeComponent } from './SomeComponent.tsx';
export * from './moreComponents.tsx';
export { default as SomeComponent2 } from './SomeComponent2.tsx';
export { default as SomeComponent3 } from './SomeComponent3.tsx';
is this expect to work? Im getting this error when running deno task dev:
error: Uncaught (in promise) Error: Missing chunk for file:///Users/sad/tmp/fresh_test_library/src/islands/mod.ts#SomeComponent
error: Uncaught (in promise) Error: Missing chunk for file:///Users/sad/tmp/fresh_test_library/src/islands/mod.ts#SomeComponent
If I comment out the SomeComponent export there, it will go to the next component exported and throw the same error
marvinh.
marvinh.2mo ago
Looks fine, this should definitely work. Do you have a repro or a snippet with which I can reproduce the error on my end?
TheSadMidDeveloper
TheSadMidDeveloperOP2mo ago
Let me check how I can share the code, but basically I tried creating a fresh project again 1. deno run -Ar jsr:@fresh/init@2.0.0-alpha.21 2. Added a folder named (whatever) with 2 files - (SomeComponent.tsx, mod.ts) 3. Create a plugin that adds it as island SomeComponent is a default export, just a button with an onClick action. mod.ts exports SomeComponent as named component The plugin
import { App } from 'fresh';
import * as islands from './whatever/mod.ts'; // only contains `SomeComponent` for now

export function somePlugin<T>(
app: App<T>,
) {
const islandsUrl = new URL('./mod.ts', import.meta.url);
for (const key of Object.keys(islands)) {
app.island(islandsUrl, key, islands[key]);
}
}
import { App } from 'fresh';
import * as islands from './whatever/mod.ts'; // only contains `SomeComponent` for now

export function somePlugin<T>(
app: App<T>,
) {
const islandsUrl = new URL('./mod.ts', import.meta.url);
for (const key of Object.keys(islands)) {
app.island(islandsUrl, key, islands[key]);
}
}
and the dev.ts file
import { Builder } from "fresh/dev";
import { app } from "./main.ts";
import { somePlugin } from './plugin.ts'

const builder = new Builder();

somePlugin(app)

// other code
import { Builder } from "fresh/dev";
import { app } from "./main.ts";
import { somePlugin } from './plugin.ts'

const builder = new Builder();

somePlugin(app)

// other code
and running deno task dev already throws an error:
error: Uncaught (in promise) Error: Missing chunk for file:///Users/tmp/sad/fresh-project-test-plugin/plugin/mod.ts#SomeComponent
error: Uncaught (in promise) Error: Missing chunk for file:///Users/tmp/sad/fresh-project-test-plugin/plugin/mod.ts#SomeComponent
It errors here https://github.com/denoland/fresh/blob/e0f65319cd48753f5b9b4784f996a0eaf7e6ebff/src/dev/builder.ts#L196
marvinh.
marvinh.2mo ago
Does it work if you move somePlugin(app) into main.ts instead of dev.ts?
TheSadMidDeveloper
TheSadMidDeveloperOP2mo ago
same output Tried to lower the version to the first alpha (2.0.0-alpha.1) to check if it might be caused by a reacent update, but still the same error The crazy thing is if you have the package deployed to JSR, it works... so this only happens on local
wobsoriano
wobsoriano2mo ago
Just ran into the same issue. What worked for me is passing pathname instead of a URL class
const url = new URL('./components/islands.ts', import.meta.url)

app.island(url.pathname, 'SignInButton', SignInButton)
app.island(url.pathname, 'SignOutButton', SignOutButton)
const url = new URL('./components/islands.ts', import.meta.url)

app.island(url.pathname, 'SignInButton', SignInButton)
app.island(url.pathname, 'SignOutButton', SignOutButton)
If you pass a URL, it'll get the href here - https://github.com/denoland/fresh/blob/e0f65319cd48753f5b9b4784f996a0eaf7e6ebff/src/app.ts#L87 Would love to contribute if we want to use pathname in that specific line instead