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

feat: implement fetchable runner #18338

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

sheremet-va
Copy link
Member

@sheremet-va sheremet-va commented Oct 11, 2024

Description

Rought but working concept of a fetchable runner (related to #18191)

Note that this is not a fetchable environment (a bit confusing, is it?).

const server = await createServer()
await server.listen()

// can be initiated in a another process
const runner = createFetchableModuleRunner({
  root: process.env.VITE_CONFIG_ROOT,
  serverURL: process.env.VITE_SERVER_URL,
  environmentName: process.env.VITE_ENVIRONMENT_NAME,
})

Copy link

stackblitz bot commented Oct 11, 2024

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/transformRequest.ts:271
// if (!ensureServingAccess(moduleUrl, server, res, next)) {
// return
// }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need help with this one 🤔 @patak-dev

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to my comment #18338 (comment), exposing fetchModule from a bridge server would essentially have the same issue, but what I did is to protect the endpoint by requiring key, which is only available to child process hi-ogawa/vite-environment-examples#132

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a bridge, it's not a fetchable environment anymore, is it? This seems like completely unrelated approach

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's probably right to say it's a completely independent concept from "fetchable environment" concept.

Bridge server is only to help a few http rpc between environment implementation and runtime side communication, which can include fetchModule. Then, independently from such logic, devEnv.dispatchFetch(request) can be implemented as proxing the server spawned inside runtime.

For child process specifically, rpc can be implemented with stdio (or if nodejs child process, onmessage/postMessage works too). And if it's miniflare, then it already supports fairly arbitrary communication between main process and runtime, so that's used.

My impression is that even if we provide this middleware to expose fetchModule, I would imagine environment implementation would require other communication primitive for other need, so this middleware alone doesn't seem useful in practice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would imagine environment implementation would require other communication primitive for other need

For what needs? How would that achieve those needs in production then if fetch is not enough?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is the only need I had, but runner side can tell its randomly allocated server port to the environment, so they can proxy dispatchFetch later https://github.com/netlify/netlify-vite-environment/blob/f4c2e77d832b3f33df57d2a30bdc8de0a4ab5ca7/packages/vite-environment-provider-netlify/src/runtime-bridge.ts#L54-L55

This is only about "dev" environment implementation specifics, which is hidden from production framework/app implementations.

@sheremet-va sheremet-va marked this pull request as ready for review October 12, 2024 12:03
@hi-ogawa
Copy link
Collaborator

This looks very natural to have, but one thing I worry is that requiring server.listen before creating a runner seems not so intuitive. For example, during DevEnvironment.init, server is not started, so environment integration would require delaying runner initialization further (though when init runs might change for #18264).

To mitigate this limitation, I saw Netlify made a "bridge" server for their environment's own purpose, which allows communicating between runner and environment in more arbitrary manner. https://github.com/netlify/netlify-vite-environment/blob/main/packages/vite-environment-provider-netlify/src/runtime-bridge.ts

Though it feels pretty odd that for Vite to spawn yet another server, Netlify's approach seems simpler to reason about to implement environment, so I did something similar in my child process poc https://github.com/hi-ogawa/vite-environment-examples/tree/main/examples/child-process.

@sheremet-va
Copy link
Member Author

This looks very natural to have, but one thing I worry is that requiring server.listen before creating a runner seems not so intuitive. For example, during DevEnvironment.init, server is not started, so environment integration would require delaying runner initialization further (though when init runs might change for #18264).

This is not the case though. listen needs to be called before you import the module, not before you create a runner.

@sheremet-va
Copy link
Member Author

@Rich-Harris would love to hear your thoughts on the implementation and @hi-ogawa feedback

@hi-ogawa
Copy link
Collaborator

This is not the case though. listen needs to be called before you import the module, not before you create a runner.

For child process case I have in mind, spawning child process needs to be delayed to be able to pass VITE_SERVER_URL during spawn time. Or alternatively, it requires communication from server to runtime to pass VITE_SERVER_URL after spawned.

@hi-ogawa
Copy link
Collaborator

Ah, forgot to add that this middleware should work for web worker environment/runner https://github.com/hi-ogawa/vite-environment-examples/tree/main/examples/web-worker. serverUrl can be taken from self.location.origin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants