Skip to content

Commit

Permalink
vite 6
Browse files Browse the repository at this point in the history
  • Loading branch information
nitedani committed May 5, 2024
1 parent 8c7e33b commit 818ad20
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 78 deletions.
2 changes: 1 addition & 1 deletion examples/vike/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"typescript": "^5.3.3",
"vike": "0.4.161",
"vike-node": "^0.0.1",
"vite": "6.0.0-alpha.0"
"vite": "6.0.0-alpha.11"
},
"type": "module"
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
},
"pnpm": {
"overrides": {
"vike-node": "link:./packages/vike-node/"
"vike-node": "link:./packages/vike-node/",
"vite": "6.0.0-alpha.11"
},
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
}
2 changes: 1 addition & 1 deletion packages/vike-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"fastify": "^4.26.1",
"typescript": "^5.3.3",
"vike": "0.4.161",
"vite": "6.0.0-alpha.0"
"vite": "6.0.0-alpha.11"
},
"typesVersions": {
"*": {
Expand Down
180 changes: 135 additions & 45 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,14 @@ export { devServerPlugin }
import pc from '@brillout/picocolors'
import { BirpcReturn, createBirpc } from 'birpc'
import { ChildProcess, fork } from 'child_process'
import { EnvironmentModuleNode, HMRChannel, ModuleNode, Plugin, ViteDevServer } from 'vite'
import {
DevEnvironment,
EnvironmentModuleNode,
HMRChannel,
Plugin,
RemoteEnvironmentTransport,
ViteDevServer
} from 'vite'
import { ConfigVikeNodeResolved } from '../../../types.js'
import { assert } from '../../../utils/assert.js'
import { getConfigVikeNode } from '../../utils/getConfigVikeNode.js'
Expand All @@ -19,6 +26,8 @@ let vite: ViteDevServer
let rpc: BirpcReturn<ClientFunctions, ServerFunctions>
let cp: ChildProcess | undefined
let entryAbs: string
let onMessageHandler: (data: any) => void
let hmrHandler: ((data: any) => void) | undefined

function devServerPlugin(): Plugin {
let resolvedConfig: ConfigVikeNodeResolved
Expand All @@ -34,6 +43,40 @@ function devServerPlugin(): Plugin {
// this needs to be exposed in containers
port: viteHmrPort
}
},
environments: {
ssr: {
dev: {
createEnvironment(name, config) {
const hot = createSimpleHMRChannel({
name,
post: (data) => rpc.onHmrReceive(data),
on: (listener) => {
hmrHandler = listener
return () => {
hmrHandler = undefined
}
},
async onRestartWorker() {
await restartWorker()
vite.environments.client.hot.send({ type: 'full-reload' })
}
})

return new DevEnvironment('ssr', config, {
runner: {
transport: new RemoteEnvironmentTransport({
send: (data) => rpc.onViteTransportMessage(data),
onMessage: (handler) => {
onMessageHandler = handler
}
})
},
hot
})
}
}
}
}
}
},
Expand All @@ -42,7 +85,7 @@ function devServerPlugin(): Plugin {
assert(resolvedConfig.server)
},
async hotUpdate(ctx) {
console.log(ctx.environment.name, ctx.modules, ctx.type)
// console.log(ctx.environment.name, ctx.modules, ctx.type)
if (ctx.environment.name !== 'ssr') {
return
}
Expand All @@ -52,29 +95,6 @@ function devServerPlugin(): Plugin {
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[]
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_) {
Expand All @@ -90,6 +110,7 @@ function devServerPlugin(): Plugin {
}
}
})

vite.printUrls = () => {}
restartWorker()
}
Expand All @@ -106,16 +127,7 @@ function devServerPlugin(): Plugin {
assert(resolvedConfig.server)
const index = resolvedConfig.server.entry.index

const originalInvalidateModule = vite.moduleGraph.invalidateModule.bind(vite.moduleGraph)
vite.moduleGraph.invalidateModule = (mod, ...rest) => {
if (mod.id) {
// timeout error
rpc.deleteByModuleId(mod.id).catch(() => {})
}
return originalInvalidateModule(mod, ...rest)
}

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

Expand All @@ -134,16 +146,11 @@ function devServerPlugin(): Plugin {

rpc = createBirpc<ClientFunctions, ServerFunctions>(
{
async fetchModule(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
// update: maybe it's fixed
// await import(id)
}
return result
onViteTransportMessage(data) {
return onMessageHandler(data)
},

// These are used by Vike on the other side
moduleGraphResolveUrl(url: string) {
return vite.environments.ssr.moduleGraph.resolveUrl(url)
},
Expand Down Expand Up @@ -184,7 +191,7 @@ function devServerPlugin(): Plugin {

// This is the minimal representation the Vike runtime needs
function convertToMinimalModuleNode(
node: EnvironmentModuleNode ,
node: EnvironmentModuleNode,
cache: Map<EnvironmentModuleNode, MinimalModuleNode> = new Map()
): MinimalModuleNode {
// If the node is in the cache, return the cached version
Expand All @@ -210,3 +217,86 @@ function convertToMinimalModuleNode(

return minimalNode
}

function createSimpleHMRChannel(options: {
name: string
post: (data: any) => any
on: (listener: (data: any) => void) => () => void
onRestartWorker: () => void
}): HMRChannel {
const listerMap = new DefaultMap<string, Set<Function>>(() => new Set())
let dispose: (() => void) | undefined

return {
name: options.name,
listen() {
dispose = options.on((payload) => {
for (const f of listerMap.get(payload.event)) {
f(payload.data)
}
})
},
close() {
dispose?.()
dispose = undefined
},
on(event: string, listener: (...args: any[]) => any) {
listerMap.get(event).add(listener)
},
off(event: string, listener: (...args: any[]) => any) {
listerMap.get(event).delete(listener)
},
send(...args: any[]) {
let payload: any
if (typeof args[0] === 'string') {
payload = {
type: 'custom',
event: args[0],
data: args[1]
}
} else {
payload = args[0]
}

if (payload.triggeredBy && isImported(payload.triggeredBy)) {
options.onRestartWorker()
return
}

options.post(payload)
}
}
}

class DefaultMap<K, V> extends Map<K, V> {
constructor(
private defaultFn: (key: K) => V,
entries?: Iterable<readonly [K, V]>
) {
super(entries)
}

override get(key: K): V {
if (!this.has(key)) {
this.set(key, this.defaultFn(key))
}
return super.get(key)!
}
}

function isImported(id: string) {
const moduleNode = vite.environments.ssr.moduleGraph.getModuleById(id)
assert(moduleNode)
const modules = new Set([moduleNode])
for (const module of modules) {
if (module.file === entryAbs) {
return true
}

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

return false
}
6 changes: 3 additions & 3 deletions packages/vike-node/src/plugin/plugins/devServer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ type WorkerData = {

type ClientFunctions = {
start(workerData: WorkerData): void
deleteByModuleId(modulePath: string): boolean
invalidateDepTree(ids: string[]): void
onViteTransportMessage(data: any): void
onHmrReceive: (data: any) => void
}

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

type ServerFunctions = {
fetchModule(id: string, importer?: string): Promise<FetchResult>
moduleGraphResolveUrl(url: string): Promise<ResolvedUrl>
moduleGraphGetModuleById(id: string): MinimalModuleNode | undefined
transformIndexHtml(url: string, html: string, originalUrl?: string): Promise<string>
onViteTransportMessage(data: any): void
}
40 changes: 29 additions & 11 deletions packages/vike-node/src/plugin/plugins/devServer/worker.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { createBirpc } from 'birpc'
import { ESModulesEvaluator, ModuleRunner } from 'vite/module-runner'
import { ESModulesEvaluator, ModuleRunner, RemoteRunnerTransport } 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 runner: ModuleRunner
let entry_: string

let hmrHandler: (data: any) => void
let viteTransportHandler: (data: any) => void
const rpc = createBirpc<ServerFunctions, ClientFunctions>(
{
onHmrReceive(data) {
hmrHandler(data)
},
onViteTransportMessage(data) {
viteTransportHandler(data)
},
async start(workerData: WorkerData) {
const { entry, viteConfig } = workerData
entry_ = entry
// This is the minimal required object for vike + telefunc to function
const globalObject = {
viteConfig,
Expand Down Expand Up @@ -48,18 +53,31 @@ const rpc = createBirpc<ServerFunctions, ClientFunctions>(
runner = new ModuleRunner(
{
root: viteConfig.root,
transport: { fetchModule: rpc.fetchModule },
hmr: false
transport: new RemoteRunnerTransport({
send(data) {
rpc.onViteTransportMessage(data)
},
onMessage(handler) {
viteTransportHandler = handler
}
}),
hmr: {
connection: {
onUpdate(callback) {
hmrHandler = callback
},
isReady() {
return true
},
send(messages) {}
}
}
},
new ESModulesEvaluator()
)
logViteInfo('Loading server entry')
await runner.import(entry)
},
async invalidateDepTree(mods) {
await runner.moduleCache.invalidateDepTree(mods)
},
deleteByModuleId: (mod) => runner.moduleCache.deleteByModuleId(mod)
}
},
{
post: (data) => {
Expand Down
Loading

0 comments on commit 818ad20

Please sign in to comment.