返回 slidev
useDevServer.ts
根目录 / packages / vscode / src / composables / useDevServer.ts
1 import type { EffectScope, ShallowRef } from 'reactive-vscode'
2 import type { Terminal } from 'vscode'
3 import type { SlidevProject } from '../projects'
4 import { basename } from 'pathe'
5 import { effectScope, onScopeDispose, shallowRef, useAbsoluteUri, useDisposable } from 'reactive-vscode'
6 import { env, window } from 'vscode'
7 import { config } from '../configs'
8 import { getSlidesTitle } from '../utils/getSlidesTitle'
9 import { useServerDetector } from './useServerDetector'
10
11 export interface SlidevServer {
12 scope: EffectScope
13 terminal: ShallowRef<Terminal | null>
14 start: () => void
15 }
16
17 export function useDevServer(project: SlidevProject) {
18 const { allocPort, redetect } = useServerDetector()
19
20 const { port, server } = project
21 if (server.value)
22 return server.value
23
24 const scope = effectScope(true)
25 return server.value = scope.run(() => {
26 const terminal = shallowRef<Terminal | null>(null)
27
28 async function start() {
29 if (terminal.value && terminal.value.exitStatus == null)
30 return
31
32 terminal.value = useDisposable(window.createTerminal({
33 name: getSlidesTitle(project.data),
34 cwd: project.userRoot,
35 iconPath: {
36 light: useAbsoluteUri('dist/res/logo-mono.svg').value,
37 dark: useAbsoluteUri('dist/res/logo-mono-dark.svg').value,
38 },
39 isTransient: true,
40 }))
41
42 const p = port.value ??= await allocPort()
43 const args = [
44 JSON.stringify(basename(project.entry)),
45 `--port ${p}`,
46 env.remoteName != null ? '--remote' : '',
47 ].filter(Boolean).join(' ')
48 // eslint-disable-next-line no-template-curly-in-string
49 terminal.value.sendText(config['dev-command'].replaceAll('${args}', args).replaceAll('${port}', `${p}`))
50
51 let intervalCount = 0
52 const maxIntervals = 100
53 const interval = setInterval(async () => {
54 intervalCount++
55 const ready = await redetect(p)
56 if (ready || intervalCount >= maxIntervals) {
57 clearInterval(interval)
58 }
59 }, 500)
60 }
61
62 onScopeDispose(() => {
63 close()
64 server.value = null
65 })
66
67 return {
68 scope,
69 terminal,
70 start,
71 }
72 })!
73 }
74
74 lines TYPESCRIPT