chore: sync
This commit is contained in:
1 parent
8b1ec67609
commit
ac65b75c73
6 files changed
+179
-10
No files matched your search
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 启动文档站 dev server,启动前挑一个真正空闲的端口。
|
||||
*
|
||||
* 为什么不用 Nuxt 自带的端口回退:Nuxt 靠“试绑 host”判断端口是否空闲,而 Windows 上 Node
|
||||
* 默认开启 SO_REUSEADDR,**允许多个进程绑定同一个 addr:port**,于是“能不能绑上”根本判断不出
|
||||
* 冲突 —— 3000 已被别的服务占用时,探测仍然成功,Nuxt 就继续用 3000。
|
||||
*
|
||||
* 因此这里改用“实际建立 TCP 连接”来判断:只要 127.0.0.1 或 ::1 任一能连上,就说明该端口
|
||||
* 正在被监听(可覆盖占用方绑在 0.0.0.0 / 127.0.0.1 / ::1 的所有常见情况),然后依次向上找。
|
||||
*
|
||||
* 起始端口:DOCS_PORT > PORT > 3000。
|
||||
*/
|
||||
import { spawn } from 'node:child_process'
|
||||
import { connect } from 'node:net'
|
||||
|
||||
const start = Number(process.env.DOCS_PORT || process.env.PORT || 3000)
|
||||
const MAX_TRIES = 100
|
||||
|
||||
/** 能否连接到 host:port(能连上即为“正在被监听”) */
|
||||
function reachable(port, host) {
|
||||
return new Promise((resolve) => {
|
||||
const socket = connect({ port, host })
|
||||
const done = (busy) => {
|
||||
socket.destroy()
|
||||
resolve(busy)
|
||||
}
|
||||
socket.setTimeout(400)
|
||||
socket.once('connect', () => done(true))
|
||||
socket.once('timeout', () => done(false))
|
||||
socket.once('error', () => done(false))
|
||||
})
|
||||
}
|
||||
|
||||
async function isBusy(port) {
|
||||
const [v4, v6] = await Promise.all([reachable(port, '127.0.0.1'), reachable(port, '::1')])
|
||||
return v4 || v6
|
||||
}
|
||||
|
||||
let port = start
|
||||
while (port < start + MAX_TRIES && (await isBusy(port))) port++
|
||||
|
||||
if (port !== start) console.log(`端口 ${start} 已被占用,改用 ${port}`)
|
||||
|
||||
const child = spawn('nuxt', ['dev', '--port', String(port)], {
|
||||
stdio: 'inherit',
|
||||
shell: true,
|
||||
})
|
||||
child.on('exit', (code) => process.exit(code ?? 0))
|
||||
Reference in new issue
Block a user