Skip to content

Commit

Permalink
feat(dev): move restart logic out to start script
Browse files Browse the repository at this point in the history
Previously, if there was a syntax error or some other exception stopping the dev server from starting up, the file change listener would not get registered and the dev server would not restart.

In this new version, the dev server will restart even after a previous run failed to parse or threw an exception.
  • Loading branch information
justmoon committed Nov 25, 2023
1 parent 07aff39 commit f9dac14
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 22 deletions.
60 changes: 53 additions & 7 deletions packages/app-dev/bin/start-development-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { installSourcemapsSupport } from "vite-node/source-map"

const log = console.info

const DEVELOPMENT_SERVER_ENTRYPOINT = "packages/app-dev/src/backend/start.ts"

const createViteServer = async () => {
const viteServer = await createServer({
logLevel: "error",
Expand Down Expand Up @@ -70,21 +72,62 @@ const getStartModule = async (
/** @type import("../src/backend/start") */
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const startModule = await viteNodeRunner.executeFile(
"packages/app-dev/src/backend/start.ts",
DEVELOPMENT_SERVER_ENTRYPOINT,
)

return startModule.default
}

const isWithinBoundary = (
/** @type import('vite').ModuleNode */ node,
/** @type Set<import('vite').ModuleNode> */ traversedModules,
/** @type Set<import('vite').ModuleNode> */ boundaryModules,
) => {
if (traversedModules.has(node)) {
return false
}
traversedModules.add(node)

if (boundaryModules.has(node)) {
return true
}

for (const importer of node.importers) {
if (isWithinBoundary(importer, traversedModules, boundaryModules)) {
return true
}
}

return false
}

log(chalk.bold(` Dassie${chalk.green("//dev")}\n`))
log(" Starting development server...\n")

const { viteServer, viteNodeServer } = await createViteServer()

const start = await getStartModule(viteServer, viteNodeServer)
let reactorPromise = start({ viteServer, viteNodeServer, restart })
let reactorPromise = start({ viteServer, viteNodeServer })
let isRestartInProgress = false

viteServer.watcher.on("change", (/** @type string */ file) => {
const { moduleGraph } = viteServer

const entrypoint = `${process.cwd()}/${DEVELOPMENT_SERVER_ENTRYPOINT}`

const changedModules = moduleGraph.getModulesByFile(file)
const boundaryModules = moduleGraph.getModulesByFile(entrypoint)
if (!changedModules || !boundaryModules) return

/**@type Set<import('vite').ModuleNode> */
const traversedModules = new Set()
for (const module of changedModules) {
if (isWithinBoundary(module, traversedModules, boundaryModules)) {
restart()
}
}
})

function restart() {
if (isRestartInProgress) return
isRestartInProgress = true
Expand All @@ -97,9 +140,12 @@ function restart() {
viteNodeServer.fetchCache = new Map()

const start = await getStartModule(viteServer, viteNodeServer)
reactorPromise = start({ viteServer, viteNodeServer, restart })
isRestartInProgress = false
})().catch((/** @type unknown */ error) => {
console.error("error in development server", { error })
})
reactorPromise = start({ viteServer, viteNodeServer })
})()
.catch((/** @type unknown */ error) => {
console.error("error in development server", { error })
})
.finally(() => {
isRestartInProgress = false
})
}
3 changes: 0 additions & 3 deletions packages/app-dev/src/backend/actors/handle-file-change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from "../constants/entrypoints"
import { vite as logger } from "../logger/instances"
import { PeeringStateStore } from "../stores/peering-state"
import { RestartCallbackUnconstructable } from "../unconstructables/restart-callback"
import { ViteNodeServer } from "../unconstructables/vite-node-server"
import { ViteServer } from "../unconstructables/vite-server"
import { RunNodesActor } from "./run-nodes"
Expand Down Expand Up @@ -61,7 +60,6 @@ const areModulesWithinBoundary = (
export const HandleFileChangeActor = (reactor: Reactor) => {
const viteServer = reactor.use(ViteServer)
const viteNodeServer = reactor.use(ViteNodeServer)
const restart = reactor.use(RestartCallbackUnconstructable)
const peeringStateStore = reactor.use(PeeringStateStore)
const runNodesActor = reactor.use(RunNodesActor)

Expand All @@ -86,7 +84,6 @@ export const HandleFileChangeActor = (reactor: Reactor) => {
developmentServerBoundaryModules,
)
) {
restart()
return
}

Expand Down
9 changes: 1 addition & 8 deletions packages/app-dev/src/backend/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ import { RegisterReactiveLoggerActor } from "./actors/register-reactive-logger"
import { RunNodesActor } from "./actors/run-nodes"
import { DebugUiServerActor } from "./actors/serve-debug-ui"
import { ListenForRpcWebSocketActor } from "./actors/serve-rpc"
import { RestartCallbackUnconstructable } from "./unconstructables/restart-callback"
import { ViteNodeServer } from "./unconstructables/vite-node-server"
import { ViteServer } from "./unconstructables/vite-server"

export interface StartParameters {
viteServer: ViteDevServer
viteNodeServer: ViteNodeServerType
restart: () => void
}

const RootActor = () =>
Expand All @@ -39,15 +37,10 @@ const RootActor = () =>
sig.run(CloseViteServerOnShutdownActor)
})

const start = async ({
viteServer,
viteNodeServer,
restart,
}: StartParameters) => {
const start = async ({ viteServer, viteNodeServer }: StartParameters) => {
const reactor = createReactor()
reactor.set(ViteServer, viteServer)
reactor.set(ViteNodeServer, viteNodeServer)
reactor.set(RestartCallbackUnconstructable, restart)
const startActor = reactor.use(RootActor)
await startActor.run(reactor)
return reactor
Expand Down

This file was deleted.

0 comments on commit f9dac14

Please sign in to comment.