-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuildHelper.ts
More file actions
85 lines (78 loc) · 2.43 KB
/
buildHelper.ts
File metadata and controls
85 lines (78 loc) · 2.43 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
import fs from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import packageJson from './package.json' with { type: 'json' }
import { fork, spawn } from 'node:child_process'
type Opts = { type: string, tscArgs: string[], renameFileArgs: string[] }
const optionsMap: Record<string, Opts> = {
esm: {
type: 'module',
tscArgs: ['--project', 'tsconfig.json', '--declaration'],
renameFileArgs: ['esm']
},
cjs: {
type: 'commonjs',
tscArgs: ['--project', 'tsconfig.cjs.json', '--declaration'],
renameFileArgs: ['cjs']
}
}
const __dirname = dirname(fileURLToPath(import.meta.url))
const withTempTypeWrapper = async (newType: string, run: () => Promise<void> | void) => {
const suffix = crypto.randomUUID()
const tempFilePath = join(__dirname, `~$package.json.${suffix}`)
const packageJsonPath = join(__dirname, 'package.json')
await fs.copyFile(packageJsonPath, tempFilePath)
try {
const newContents = structuredClone(packageJson)
newContents.type = newType
await fs.writeFile(packageJsonPath, JSON.stringify(newContents, undefined, 2))
await run()
} finally {
await fs.copyFile(tempFilePath, packageJsonPath, fs.constants.COPYFILE_FICLONE)
await fs.unlink(tempFilePath)
}
}
const buildInternal = async (opts: Opts) => {
await new Promise<void>((resolve, reject) => {
const tsc = spawn('tsc', opts.tscArgs, {
env: {
...process.env,
PATH: [join(__dirname, 'node_modules', '.bin'), process.env.PATH].filter(Boolean).join(':')
},
stdio: 'inherit'
})
tsc.on('close', (code) => {
if (code !== 0) {
reject(new Error(`[tsc] code ${code}`))
} else {
resolve()
}
})
})
await new Promise<void>((resolve, reject) => {
const rename = fork(
new URL('./renameFiles.mjs', import.meta.url), opts.renameFileArgs, { stdio: 'inherit' }
)
rename.on('close', (code) => {
if (code !== 0) {
reject(new Error(`[rename] code ${code}`))
} else {
resolve()
}
})
})
}
const build = async (opts: Opts) => {
if (packageJson.type !== opts.type) {
return withTempTypeWrapper(opts.type, () => buildInternal(opts))
} else {
return buildInternal(opts)
}
}
if (process.argv[2] === 'esm') {
await build(optionsMap.esm)
} else if (process.argv[2] === 'cjs') {
await build(optionsMap.cjs)
} else {
console.error('Invalid build type')
}