Skip to content
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

Fresh should bundle worker entrypoints #1398

Open
lucacasonato opened this issue Jul 3, 2023 · 5 comments · May be fixed by #1407
Open

Fresh should bundle worker entrypoints #1398

lucacasonato opened this issue Jul 3, 2023 · 5 comments · May be fixed by #1407
Labels
feat New feature or request

Comments

@lucacasonato
Copy link
Member

Right now using workers in Fresh is kinda painful. For example, I want to load a worker in an island. I would expect to be able to do this with:

const worker = new Worker(import.meta.resolve("./worker.ts"), { type: "module" });

However, Fresh does not pick up on this import and thus does not transpile / bundle the worker and replace import.meta.resolve with a static string.

At some point we'll have a JS standard way of doing this, but for now we should use the commonly accepted stupid way of doing this.

import module myWorker from "./worker.ts";
myWorker instanceof Module; // true

const worker = new Worker(myWorker);

// or

const worker = new Worker();
worker.addModule(myWorker);
@lucacasonato lucacasonato added the feat New feature or request label Jul 3, 2023
@marvinhagemeister
Copy link
Collaborator

Related esbuild issue: evanw/esbuild#2866

@deer
Copy link
Contributor

deer commented Jul 3, 2023

I looked at this for a bit, since I think this would be a nice area of the code base to explore. I created an island like this:

import { useEffect, useRef } from "preact/hooks";

export default function IslandWithWorker() {
  const workerRef = useRef<Worker | null>(null);

  useEffect(() => {
    workerRef.current = new Worker(
      new URL("../workers/myFirstWorker.ts", import.meta.url),
      { type: "module" },
    );

    if (workerRef.current) {
      workerRef.current.postMessage("Message from main thread");
      workerRef.current.onmessage = ({ data }) => {
        console.log("Received message in main thread", data);
      };
    }

    return () => {
      if (workerRef.current) {
        workerRef.current.terminate();
      }
      workerRef.current = null;
    };
  }, []);

  return <div>hello from the island</div>;
}

and my worker/myFirstWorker.ts like this:

self.onmessage = ({ data }) => {
  console.log("Received message in worker", data);
  self.postMessage("this is working");
};

and finally a route:

import { Handlers } from "../../../server.ts";
import IslandWithWorker from "../islands/IslandWithWorker.tsx";

export const handler: Handlers = {
  GET(_req, ctx) {
    return ctx.render();
  },
};

export default function Home() {
  return (
    <div>
      <IslandWithWorker />
    </div>
  );
}

I was successfully able to get this working, in that the chrome console says:

Received message in worker Message from main thread
Received message in main thread this is working

My approach definitely needs to change though, since I wasn't doing anything with esbuild plugins. I'll try that next. If either of you have a more realistic use case, please feel free to share. This is literally my first worker 😅

@lucacasonato
Copy link
Member Author

Oh how curious that this works already! Do you have a repo you can share? I'm suprised esbuild picks up on the new URL("../workers/myFirstWorker.ts", import.meta.url) that easy.

@deer
Copy link
Contributor

deer commented Jul 3, 2023

No, sorry for not being clear. I had hacked some stuff into #bundleAssetRoute to modify the island manually. This isn't really a scalable approach.

@deer deer linked a pull request Jul 4, 2023 that will close this issue
@deer
Copy link
Contributor

deer commented Jul 4, 2023

Hey @lucacasonato, I created a draft PR where I have my test case and implementation. I did manage to get the esbuild plugin approach working, so I removed my total hack where I was doing it almost manually.

@marvinhagemeister marvinhagemeister modified the milestone: Fresh 1.4 Jul 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants