Skip to content

Commit

Permalink
vite 6
Browse files Browse the repository at this point in the history
  • Loading branch information
nitedani committed Apr 7, 2024
1 parent 5466172 commit 8c7e33b
Show file tree
Hide file tree
Showing 11 changed files with 919 additions and 623 deletions.
12 changes: 8 additions & 4 deletions examples/vike/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
{
"scripts": {
"dev": "vite",
"dev": "node --trace-warnings node_modules/vite/bin/vite",
"build": "vite build",
"prepare": "pnpm prisma generate && pnpm prisma db push",
"prod": "pnpm run build && cp ./prisma/test.db ./dist/server/node_modules/.prisma/client && cross-env NODE_ENV=production node dist/server/index.mjs"
},
"dependencies": {
"@hattip/adapter-node": "^0.0.42",
"@brillout/json-serializer": "^0.5.8",
"@hattip/adapter-node": "^0.0.45",
"@hattip/router": "^0.0.45",
"@hono/node-server": "^1.9.0",
"@node-rs/argon2": "^1.7.2",
"@prisma/client": "^5.9.1",
"@types/express": "^4.17.21",
Expand All @@ -16,15 +19,16 @@
"cross-env": "^7.0.3",
"express": "^4.18.2",
"fastify": "^4.26.1",
"hono": "^4.1.5",
"prisma": "^5.9.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "^0.33.2",
"telefunc": "^0.1.71",
"typescript": "^5.3.3",
"vike": "^0.4.161",
"vike": "0.4.161",
"vike-node": "^0.0.1",
"vite": "npm:@nitedani/[email protected]"
"vite": "6.0.0-alpha.0"
},
"type": "module"
}
32 changes: 21 additions & 11 deletions examples/vike/server/index-hattip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,42 @@ import { telefunc } from 'telefunc'
import { vike } from 'vike-node/web'
import { init } from '../database/todoItems.js'
import { createServer } from '@hattip/adapter-node'
import { createRouter } from '@hattip/router'

startServer()

async function startServer() {
await init()
// app.all('/_telefunc', async (req, res) => {
// const context = {}
// const httpResponse = await telefunc({ url: req.originalUrl, method: req.method, body: req.body as string, context })
// const { body, statusCode, contentType } = httpResponse
// res.status(statusCode).type(contentType).send(body)
// })
const app = createRouter()

const server = createServer(async (ctx) => {
app.use('/_telefunc', async (ctx) => {
const httpResponse = await telefunc({
url: ctx.request.url,
method: ctx.request.method,
body: await ctx.request.text()
})
return new Response(httpResponse.body, {
status: httpResponse.statusCode,
headers: {
'Content-Type': httpResponse.contentType
}
})
})

app.use('*', async (ctx) => {
const res = await vike({
url: ctx.platform.request.url!,
url: ctx.request.url,
headers: ctx.request.headers
})
if (!res) return new Response('Not Found', { status: 404 })
return new Response(res.stream, {
return new Response(res.body, {
status: res.status,
headers: res.headers
})
})

const server = createServer(app.buildHandler())
const port = process.env.PORT || 3000
server.listen(+port)
console.log(`Server running at http://localhost:${port}`)
}

// entry-node.js
43 changes: 43 additions & 0 deletions examples/vike/server/index-hono.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { telefunc } from 'telefunc'
import { vike } from 'vike-node/web'
import { init } from '../database/todoItems.js'
import { createAdaptorServer } from '@hono/node-server'
import { Hono } from 'hono'

startServer()

async function startServer() {
await init()
const app = new Hono()

app.use('/_telefunc', async (ctx) => {
const httpResponse = await telefunc({
url: ctx.req.url,
method: ctx.req.method,
body: await ctx.req.text()
})
return new Response(httpResponse.body, {
status: httpResponse.statusCode,
headers: {
'Content-Type': httpResponse.contentType
}
})
})

app.use('*', async (ctx) => {
const res = await vike({
url: ctx.req.url,
headers: ctx.req.header()
})
if (!res) return new Response('Not Found', { status: 404 })
return new Response(res.body, {
status: res.status,
headers: res.headers
})
})

const server = createAdaptorServer(app)
const port = process.env.PORT || 3000
server.listen(+port)
console.log(`Server running at http://localhost:${port}`)
}
4 changes: 2 additions & 2 deletions packages/vike-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"@types/node": "^20.11.19",
"fastify": "^4.26.1",
"typescript": "^5.3.3",
"vike": "^0.4.161",
"vite": "npm:@nitedani/[email protected]"
"vike": "0.4.161",
"vite": "6.0.0-alpha.0"
},
"typesVersions": {
"*": {
Expand Down
24 changes: 14 additions & 10 deletions packages/vike-node/src/plugin/plugins/commonConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@ export { commonConfig }
import type { Plugin } from 'vite'
import { ConfigVikeNodeResolved } from '../../types.js'
import { resolveConfig } from '../utils/resolveConfig.js'
import type { Config } from 'vike/types'

function commonConfig(): Plugin {
return {
name: 'vike-node:commonConfig',
enforce: 'pre',
configResolved(config) {
const server = { entry: './server/index-hattip.ts', standalone: true }
config(config, env) {
const server = { entry: './server/index-hono.ts', standalone: true }
const resolvedConfig: ConfigVikeNodeResolved = resolveConfig({ server })
;(config as Record<string, unknown>).configVikeNode = resolvedConfig

console.log(resolvedConfig)

if (typeof config.ssr.external !== 'boolean') {
config.ssr.external ??= []
config.ssr.external.push(...resolvedConfig.server.native)
return {
environments: {
ssr: {
resolve: { external: resolvedConfig.server.native }
},
client: {
resolve: { external: resolvedConfig.server.native }
}
},
optimizeDeps: {
exclude: resolvedConfig.server.native,
}
}
config.optimizeDeps.exclude ??= []
config.optimizeDeps.exclude.push(...resolvedConfig.server.native)
}
}
}
52 changes: 40 additions & 12 deletions packages/vike-node/src/plugin/plugins/devServer/devServerPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export { devServerPlugin }
import pc from '@brillout/picocolors'
import { BirpcReturn, createBirpc } from 'birpc'
import { ChildProcess, fork } from 'child_process'
import { HMRChannel, ModuleNode, Plugin, ViteDevServer } from 'vite'
import { EnvironmentModuleNode, HMRChannel, ModuleNode, Plugin, ViteDevServer } from 'vite'
import { ConfigVikeNodeResolved } from '../../../types.js'
import { assert } from '../../../utils/assert.js'
import { getConfigVikeNode } from '../../utils/getConfigVikeNode.js'
Expand All @@ -18,6 +18,7 @@ let ws: HMRChannel | undefined
let vite: ViteDevServer
let rpc: BirpcReturn<ClientFunctions, ServerFunctions>
let cp: ChildProcess | undefined
let entryAbs: string

function devServerPlugin(): Plugin {
let resolvedConfig: ConfigVikeNodeResolved
Expand All @@ -40,22 +41,45 @@ function devServerPlugin(): Plugin {
resolvedConfig = getConfigVikeNode(config)
assert(resolvedConfig.server)
},
async handleHotUpdate(ctx) {
async hotUpdate(ctx) {
console.log(ctx.environment.name, ctx.modules, ctx.type)
if (ctx.environment.name !== 'ssr') {
return
}

if (!cp) {
await restartWorker()
return
ctx.server.environments.client.hot.send({ type: 'full-reload' })
return []
}

if (!ctx.modules.length) return []
const mods = ctx.modules.map((m) => m.id).filter(Boolean) as string[]
if (!mods.length) return
const shouldRestart = await rpc.invalidateDepTree(mods)
await rpc.invalidateDepTree(mods)
const modules = new Set(ctx.modules)
let shouldRestart = false
for (const module of modules) {
if (module.file === entryAbs) {
shouldRestart = true
break
}

for (const importerInner of module.importers) {
modules.add(importerInner)
}
}

if (shouldRestart) {
await restartWorker()
ctx.server.environments.client.hot.send({ type: 'full-reload' })
}

return []
},
// called on start & vite.config.js changes
configureServer(vite_) {
vite = vite_
ws = vite.hot.channels.find((ch) => ch.name === 'ws')
ws = vite.environments.client.hot
vite.bindCLIShortcuts = () =>
bindCLIShortcuts({
onRestart: async () => {
Expand Down Expand Up @@ -91,11 +115,15 @@ function devServerPlugin(): Plugin {
return originalInvalidateModule(mod, ...rest)
}

const indexResolved = await vite.pluginContainer.resolveId(index, undefined)
assert(indexResolved?.id)
entryAbs = indexResolved.id

//@ts-ignore
const configVikePromise = await vite.config.configVikePromise

const workerData: WorkerData = {
entry: index,
entry: entryAbs,
viteConfig: { root: vite.config.root, configVikePromise }
}
cp = fork(workerPath, {
Expand All @@ -107,7 +135,7 @@ function devServerPlugin(): Plugin {
rpc = createBirpc<ClientFunctions, ServerFunctions>(
{
async fetchModule(id, importer) {
const result = await vite.ssrFetchModule(id, importer)
const result = await vite.environments.ssr.fetchModule(id, importer)
if (resolvedConfig.server.native.includes(id)) {
// sharp needs to load the .node file on this thread for some reason
// maybe it's the case for other natives as well
Expand All @@ -117,10 +145,10 @@ function devServerPlugin(): Plugin {
return result
},
moduleGraphResolveUrl(url: string) {
return vite.moduleGraph.resolveUrl(url)
return vite.environments.ssr.moduleGraph.resolveUrl(url)
},
moduleGraphGetModuleById(id: string) {
const module = vite.moduleGraph.getModuleById(id)
const module = vite.environments.ssr.moduleGraph.getModuleById(id)
if (!module) {
return module
}
Expand Down Expand Up @@ -156,8 +184,8 @@ function devServerPlugin(): Plugin {

// This is the minimal representation the Vike runtime needs
function convertToMinimalModuleNode(
node: ModuleNode,
cache: Map<ModuleNode, MinimalModuleNode> = new Map()
node: EnvironmentModuleNode ,
cache: Map<EnvironmentModuleNode, MinimalModuleNode> = new Map()
): MinimalModuleNode {
// If the node is in the cache, return the cached version
if (cache.has(node)) {
Expand Down
9 changes: 5 additions & 4 deletions packages/vike-node/src/plugin/plugins/devServer/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export type { ClientFunctions, MinimalModuleNode, ServerFunctions, WorkerData }

import type { ModuleNode, ResolvedUrl } from 'vite'
import type { FetchResult } from 'vite/runtime'
import type { FetchResult, EnvironmentModuleNode, ResolvedUrl } from 'vite'

type WorkerData = {
entry: string
Expand All @@ -14,10 +13,12 @@ type WorkerData = {
type ClientFunctions = {
start(workerData: WorkerData): void
deleteByModuleId(modulePath: string): boolean
invalidateDepTree(ids: string[]): boolean
invalidateDepTree(ids: string[]): void
}

type MinimalModuleNode = Pick<ModuleNode, 'id' | 'url' | 'type'> & { importedModules: Set<MinimalModuleNode> }
type MinimalModuleNode = Pick<EnvironmentModuleNode, 'id' | 'url' | 'type'> & {
importedModules: Set<MinimalModuleNode>
}

type ServerFunctions = {
fetchModule(id: string, importer?: string): Promise<FetchResult>
Expand Down
28 changes: 10 additions & 18 deletions packages/vike-node/src/plugin/plugins/devServer/worker.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createBirpc } from 'birpc'
import { ESModulesRunner, ViteRuntime } from 'vite/runtime'
import { ESModulesEvaluator, ModuleRunner } from 'vite/module-runner'
import { setIsWorkerEnv } from '../../../runtime/env.js'
import { logViteInfo } from '../../utils/logVite.js'
import type { ClientFunctions, ServerFunctions, WorkerData } from './types.js'

let runtime: ViteRuntime
let runner: ModuleRunner
let entry_: string

const rpc = createBirpc<ServerFunctions, ClientFunctions>(
Expand All @@ -23,7 +23,7 @@ const rpc = createBirpc<ServerFunctions, ClientFunctions>(
hasErrorLogged: () => false
}
},
ssrLoadModule: (id: string) => runtime.executeUrl(id),
ssrLoadModule: (id: string) => runner.import(id),
// called by telefunc
ssrFixStacktrace: (_err: unknown) => {},
transformIndexHtml: rpc.transformIndexHtml,
Expand All @@ -45,29 +45,21 @@ const rpc = createBirpc<ServerFunctions, ClientFunctions>(
viteDevServer: globalObject.viteDevServer
}

runtime = new ViteRuntime(
runner = new ModuleRunner(
{
fetchModule: rpc.fetchModule,
root: viteConfig.root,
transport: { fetchModule: rpc.fetchModule },
hmr: false
},
new ESModulesRunner()
new ESModulesEvaluator()
)

logViteInfo('Loading server entry')
await runtime.executeUrl(entry)
await runner.import(entry)
},
invalidateDepTree(mods) {
console.log(entry_, runtime.moduleCache.normalize(entry_), mods[0]!, runtime.moduleCache.normalize(mods[0]!));

let shouldRestart = runtime.moduleCache.isImported({
importedBy: entry_,
importedId: mods[0]!
})
runtime.moduleCache.invalidateDepTree(mods)
return shouldRestart
async invalidateDepTree(mods) {
await runner.moduleCache.invalidateDepTree(mods)
},
deleteByModuleId: (mod) => runtime.moduleCache.deleteByModuleId(mod)
deleteByModuleId: (mod) => runner.moduleCache.deleteByModuleId(mod)
},
{
post: (data) => {
Expand Down
1 change: 1 addition & 0 deletions packages/vike-node/src/runtime/renderAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type RenderAssetHttpResponse = {

function renderAsset(url: string, headers: HeadersProvided): Promise<RenderAssetHttpResponse> {
assertUsage(getIsWorkerEnv(), `${pc.cyan('renderAsset')} should only be called in development mode`)

const parsedHeaders = parseHeaders(headers)
const isUpgradeRequest = parsedHeaders.some(([key]) => key.toLowerCase() === 'upgrade')
if (isUpgradeRequest) {
Expand Down
Loading

0 comments on commit 8c7e33b

Please sign in to comment.