-
Notifications
You must be signed in to change notification settings - Fork 0
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
Vite Server RFC #3
Comments
Server codeThe user can choose between manually integrating tools, and/or using so-called plugs. // server.js
// Manual integration
export { handler }
// The Telefunc middleware that exists today
import { telefunc } from 'telefunc'
async function handler(request) {
const { url, method } = request
const { pathname } = new URL(url)
if (pathname === '/_telefunc') {
const body = await request.text()
const resp = await telefunc({ url, method, body })
return new Response(resp.body, {
headers: { 'content-type': resp.contentType },
status: resp.statusCode,
})
}
// Same with Rakkas/VPS
// ...
}
// server.js
// With plugs
export { handler }
import { createHandler } from 'vavite'
import { telefunc } from 'telefunc/vavite' // Telefunc would provide a vavite plug
import { rakkas } from 'rakkas/vavite' // Rakkas's vavite plug
// This returns a function with the same format than above: `Request => Promise<Response>`
const handler = createHandler([telefunc(), rakkas()])
Or a combination: // server.js
export const async function handler(request) {
if( someCondition ) {
// Do something custom
} else {
return createHandler([telefunc(), rakkas()])
}
} Deploy integration// worker.js
// Cloudflare Workers
import { vavite } from 'vavite/cloudflare-workers' // Vavite's adapter for Cloudflare Workers
import { handler } from './server'
addEventListener('fetch', vavite(handler))
// express.js
// Express.js
// We use ESM with `package.json['type'] === 'module'`
import express from 'express'
import { vavite } from 'vavite/express' // Vavite's adapter for Express.js
import { handler } from './server'
const app = express()
app.use(vavite(handler))
app.listen(3000)
Zero-configIn the future, we can think of a zero-config thing, if we want. (I agree that Remix's approach of showing integration code makes sense; I still think there are use cases where zero-config makes sense though.) // Zero-config mode, the user doesn't write any server code
{
"scripts": {
"dev": "vavite dev"
},
"dependencies": {
"rakkas": "*",
"telefunc": "*"
}
}
const packageJson = require('./path/to/user/package.json')
const plugs = Object.keys(packageJson.dependencies).map(dep => {
try {
const { __internal_self_installing_plug } = require(`${dep}/vavite`)
return __internal_self_installing_plug
} catch(_) {
return null
}
}) Vite agnostic project?I purposely didn't include the Vite reloader: the entire thing is completely independent of Vite. From an architectural point of view, all the That said, there would be a plugin // vite.config.js
import { vavite } from 'vavite/vite'
export default {
// This installs the `handler()` defined in `server.js` to Vite's dev server.
plugins: [ vavite('server.js') ]
}
Rename project?I'm thinking maybe we should rename the project? I actually love the name Vavite will kill Express.js and FastifyAn interesting thing is that with
Yes. Any tool that works with the vavite server-agnostic format will automatically work with any deploy provider that has a vavite adapter. For example, it's enough for NextAuth.js to be vavite-compatible to support all deploy environments. (FYI NextAuth.js currenlty doesn't support Cloudflare Workers.) There is still a use case for Express.js for tools that don't support vavite yet. But vavite will eventually kill Express.js. Epxress.js will finally die :D. How about bundling for Cloudflare Workers and Vite Server RFC?We basically don't need the RFC anymore... All we need is the goold old ticket #5935. (Merging The following would just work for Vite + Rakkas/VPS + Telefunc + Cloudflare Workers: // vite.config.js
import { vavite } from 'vavite/vite'
import { cloudflareWorkers } from 'vite-plugin-cloudflare-workers'
export default {
plugins: [
// `server.js` is the file above (which integrates Rakkas + Telefunc)
// This installs `handler()` to Vite's dev server.
vavite('server.js'),
// `worker.js` is the file above (also integrates Rakkas + Telefunc)
// This adds a custom `esbuild` bundling step to `$ vite build`
cloudflareWorkers('worker.js')
]
}
That's it!
I think that nails it. Or am I missing something here? Vavite is going to be big :-). |
// server.js
// This is hatTip code, which is:
// 1. Completely agnostic to any server environment (Express.js, Cloudflare Workers, etc.)
// 2. Completely agnostic to any bundler (Vite, webpack, etc.)
import { createHandler } from 'hattip'
import { telefunc } from 'telefunc/hattip' // Telefunc provides an hatTip adapter.
// Such adatper is completely agnostic to Vite.
import { rakkas } from 'rakkas/hattip' // Rakkas's hatTip adapter
// Returns a function with the format `Request => Promise<Response>`
export const handler = createHandler([telefunc(), rakkas()]) // worker.js
// Cloudflare Workers
import { hattip } from 'hattip/cloudflare-workers' // hatTip's adapter for Cloudflare Workers
import { handler } from './server'
addEventListener('fetch', hattip(handler)) // vite.config.js
import { hattip } from 'hattip/vite'
import { cloudflareWorkers } from 'vite-plugin-cloudflare-workers'
export default {
plugins: [
// This basically installs `handler()` to Vite's dev server.
hattip('server.js'),
// The `vite-plugin-cloudflare-workers` is completely agnostic to hatTip
// - `worker.js` is just a normal Cloudflare Workers
cloudflareWorkers('worker.js')
]
} |
The ideas are implemented by https://github.com/hattipjs/hattip. |
Authors: @cyco130, @brillout. (Let us know if you want to join us in writting this RFC.)
Structure of this RFC:
Motivation
Vite's native SSR API has enabled deep collaboration between SSR frameworks.
This RFC enables the same for deploy: there are an increasing number of deploy targets (Deno Edge, Supabase Functions, Netlify Functions, Vercel, Cloudflare Workers, AWS Lamda, AWS EC2, ...) and, instead of having each SSR framework reinventing the wheel, this RFC enables a common ecosystem of deploy integrations.
Deploy integration is deeply intertwined with the topic of how Vite should handle the server.
That's why this RFC is called
Vite Server RFC
. But the most important consequence of this RFC is a shared ecosystem of deploy integrations.Vite is becoming the "Web Compiler Commons" that powers a flourishing ecosystem of tools and frameworks. This RFC spurs that.
High-Level Goal
The goal is to enable the following DX.
We show an example for Express.js and Cloudflare Workers.
Express.js Example
The
server.js
file above showcases Middleware Mode: the user manually sets up and controls the server. Middleware Mode is needed for advanced integrations such as Stripe. (This example makes Stripe integration seem easy, but a real world integration is more complex and warrants the need for Middleware Mode.)The goal of this RFC is to also support Server Mode: the user uses Vite's built-in dev server. This means that, with Server Mode, the user doesn't have to write the
server.js
file.Server Mode is the default but the user can opt-in Middleware Mode by setting
vite.config.js#server
.CLI integration:
The CLI command
$ vite
executes the server entry defined atvite.config.js#server
(or, if missing, Vite's built-in server). It would support server HMR.The CLI command
$ vite build
builds not only the browser-side JavaScript, but also the server entry defined atvite.config.js#server
. (The user can then, for example, use the server production build for a production server on AWS EC2.)Cloudflare Workers Example
CLI integration:
The CLI
vite build
takes care of everything, including bundlingworker.js
into a single file. (Plugins, such asvite-plugin-cloudflare-workers
, can add a custom build step.)Plugins, such as
vite-plugin-cloudflare-workers
, can provide a$ vite deploy
implementation.Plan
We progressively implement parts of this RFC.
For example, we can start by implementing:
$ vite build && vite build --ssr
with$ vite build
+ enable plugins to add build step vitejs/vite#5936$ vite path/to/server.js
/vite.config.js#server
. vitejs/vite#6394$ vite deploy
.We progressively include implemented RFC parts into Vite releases. We don't foresee any breaking changes; we can hook into but not disrupt Vite's release lifecycle.
The text was updated successfully, but these errors were encountered: