forked from OPaimon/genshin-group-verif
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.mjs
More file actions
90 lines (75 loc) · 3.45 KB
/
Copy pathbuild.mjs
File metadata and controls
90 lines (75 loc) · 3.45 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
#!/usr/bin/env node
/**
* Production build script — esbuild.
*
* Why raw esbuild instead of tsup/tsdown/unbuild?
* • We ship an application, not a library — no DTS, no CJS+ESM dual-format.
* • ReScript .res.mjs inputs need `resolveExtensions` (1 line in esbuild,
* plugin in wrappers).
* • Native addon (`better-sqlite3` via `@mtcute/node`) is external; WASM
* (`@mtcute/wasm`) is handled with esbuild's `loader` option.
* • Zero abstraction tax — ~80 LOC, no wrapper to debug.
*
* Usage:
* node build.mjs — build to dist/
* node build.mjs --analyze — also print bundle analysis
*/
import { execSync } from 'node:child_process'
import { cpSync, existsSync, mkdirSync, statSync, writeFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import * as esbuild from 'esbuild'
const root = dirname(fileURLToPath(import.meta.url))
const dist = resolve(root, 'dist')
// ── 1. ReScript → .res.mjs ───────────────────────────────────
console.log('⏳ Compiling ReScript …')
execSync('pnpm res:build', { stdio: 'inherit', cwd: root })
// ── 2. Bundle ─────────────────────────────────────────────────
console.log('⏳ Bundling with esbuild …')
const result = await esbuild.build({
entryPoints: [resolve(root, 'src/main.ts')],
outfile: resolve(dist, 'main.mjs'),
bundle: true,
platform: 'node',
target: 'node22',
format: 'esm',
// Native addon used by @mtcute/node session storage — resolved at runtime
external: ['better-sqlite3'],
minify: true,
treeShaking: true,
sourcemap: true,
sourcesContent: false,
metafile: true,
// ReScript outputs .res.mjs; let esbuild resolve them
resolveExtensions: ['.ts', '.tsx', '.mjs', '.js', '.json'],
define: { 'process.env.NODE_ENV': '"production"' },
loader: { '.wasm': 'file' },
assetNames: '[name]',
// Shim `require()` for native addons in ESM context
banner: {
js: [
'// genshin-group-verif production bundle',
'import{createRequire as __cr}from"node:module";',
'const require=__cr(import.meta.url);',
].join('\n'),
},
})
// ── 3. Copy runtime data ──────────────────────────────────────
const quizDst = resolve(dist, 'bot-data/quizzes.json')
mkdirSync(dirname(quizDst), { recursive: true })
cpSync(resolve(root, 'bot-data/quizzes.json'), quizDst)
// ── 4. Report ─────────────────────────────────────────────────
writeFileSync(resolve(dist, 'metafile.json'), JSON.stringify(result.metafile))
if (process.argv.includes('--analyze')) {
console.log('\n📊 Bundle analysis:\n')
console.log(await esbuild.analyzeMetafile(result.metafile, { verbose: false }))
}
function kb(f) {
const s = existsSync(f) ? statSync(f).size : 0
return `${(s / 1024).toFixed(1)} KB`
}
console.log('\n✅ Build complete → dist/')
console.log(` main.mjs ${kb(resolve(dist, 'main.mjs'))}`)
console.log(` main.mjs.map ${kb(resolve(dist, 'main.mjs.map'))}`)
console.log(' quizzes.json ✓')
console.log('\n Run: node --enable-source-maps dist/main.mjs')