-
Notifications
You must be signed in to change notification settings - Fork 218
Expand file tree
/
Copy pathdist-tools.mjs
More file actions
130 lines (108 loc) · 3.52 KB
/
dist-tools.mjs
File metadata and controls
130 lines (108 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import fs from 'fs'
import path from 'path'
import { spawnSync } from 'child_process'
function getProject() {
const raw = (process.env.PROJECT || 'default').toString().trim()
return raw || 'default'
}
function getDistDir() {
const project = getProject()
return project === 'default' ? 'dist' : `dist-${project}`
}
function getDistAbs() {
return path.resolve(process.cwd(), getDistDir())
}
function parseArgs(argv) {
const args = argv.slice(2)
const cmd = args[0]
const rest = args.slice(1)
const ddIndex = rest.indexOf('--')
const passThrough = ddIndex >= 0 ? rest.slice(ddIndex + 1) : []
const opts = ddIndex >= 0 ? rest.slice(0, ddIndex) : rest
return { cmd, opts, passThrough }
}
function run(bin, args) {
const result = spawnSync(bin, args, {
stdio: 'inherit',
// On Windows, CLIs like "http-server" / "serve" are often .cmd shims.
// spawnSync with shell:false can fail with EINVAL in some environments (e.g. Git Bash).
shell: process.platform === 'win32',
env: process.env,
})
if (result.error) {
if (result.error.code === 'ENOENT') return { ok: false, code: 127 }
throw result.error
}
return { ok: result.status === 0, code: result.status ?? 1 }
}
function tryRun(bins, argsBuilder) {
for (const bin of bins) {
const args = argsBuilder(bin)
const r = run(bin, args)
if (r.ok) return r
}
return { ok: false, code: 1 }
}
async function main() {
const { cmd, opts, passThrough } = parseArgs(process.argv)
const project = getProject()
const distDir = getDistDir()
const distAbs = getDistAbs()
if (!cmd || ['help', '-h', '--help'].includes(cmd)) {
// eslint-disable-next-line no-console
console.log(
[
'Usage: node scripts/dist-tools.mjs <clean|serve|http> [options] [-- pass-through-args]',
'',
`PROJECT=${project}`,
`distDir=${distDir}`,
'',
'Examples:',
' PROJECT=projectA node scripts/dist-tools.mjs clean',
' PROJECT=projectA node scripts/dist-tools.mjs serve --port 5000',
' PROJECT=projectA node scripts/dist-tools.mjs http -- -p 9090 --cors',
].join('\n')
)
process.exit(0)
}
if (cmd === 'clean') {
if (fs.existsSync(distAbs)) {
await fs.promises.rm(distAbs, { recursive: true, force: true })
// eslint-disable-next-line no-console
console.log(`[dist-tools] removed ${distDir}`)
} else {
// eslint-disable-next-line no-console
console.log(`[dist-tools] skip (not exists): ${distDir}`)
}
return
}
if (cmd === 'serve') {
const portFlagIndex = opts.indexOf('--port')
const port = portFlagIndex >= 0 ? opts[portFlagIndex + 1] : '5000'
const bins = process.platform === 'win32' ? ['serve.cmd', 'serve', 'npx.cmd', 'npx'] : ['serve', 'npx']
const r = tryRun(bins, (bin) => {
if (bin.startsWith('npx')) {
return ['--yes', 'serve', '-s', distDir, '-l', port]
}
return ['-s', distDir, '-l', port]
})
process.exit(r.code)
}
if (cmd === 'http') {
const bins =
process.platform === 'win32' ? ['http-server.cmd', 'http-server', 'npx.cmd', 'npx'] : ['http-server', 'npx']
const r = tryRun(bins, (bin) => {
if (bin.startsWith('npx')) {
return ['--yes', 'http-server', distDir, ...passThrough]
}
return [distDir, ...passThrough]
})
process.exit(r.code)
}
throw new Error(`Unknown command: ${cmd}`)
}
main().catch((err) => {
// eslint-disable-next-line no-console
console.error('[dist-tools] failed:', err)
process.exit(1)
})