forked from hyperfy-xyz/hyperfy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.mjs
135 lines (127 loc) · 3.62 KB
/
build.mjs
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
131
132
133
134
135
import 'dotenv-flow/config'
import fs from 'fs-extra'
import path from 'path'
import { fork } from 'child_process'
import * as esbuild from 'esbuild'
import { fileURLToPath } from 'url'
const dev = process.argv.includes('--dev')
const dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.join(dirname, './')
const buildDir = path.join(rootDir, 'build')
await fs.emptyDir(buildDir)
/**
* Build Client
*/
const clientPublicDir = path.join(rootDir, 'src/client/public')
const clientBuildDir = path.join(rootDir, 'build/public')
const clientHtmlSrc = path.join(rootDir, 'src/client/public/index.html')
const clientHtmlDest = path.join(rootDir, 'build/public/index.html')
{
// get all public app env variables
const publicEnvs = {}
for (const key in process.env) {
if (key.startsWith('PUBLIC_')) {
const value = process.env[key]
publicEnvs[`process.env.${key}`] = JSON.stringify(value)
}
}
const clientCtx = await esbuild.context({
entryPoints: ['src/client/index.js'],
entryNames: '/[name]-[hash]',
outdir: clientBuildDir,
platform: 'browser',
format: 'esm',
bundle: true,
treeShaking: true,
minify: false,
sourcemap: true,
metafile: true,
jsx: 'automatic',
jsxImportSource: '@firebolt-dev/jsx',
define: {
// 'process.env.NODE_ENV': '"development"',
'process.env.CLIENT': 'true',
'process.env.SERVER': 'false',
...publicEnvs,
},
loader: {
'.js': 'jsx',
},
alias: {
react: 'react', // always use our own local react (jsx)
},
plugins: [
{
name: 'client-finalize-plugin',
setup(build) {
build.onEnd(async result => {
// copy over public files
await fs.copy(clientPublicDir, clientBuildDir)
// find js output file
const metafile = result.metafile
const outputFiles = Object.keys(metafile.outputs)
const jsFile = outputFiles.find(file => file.endsWith('.js')).split('build/public')[1]
// inject into html and copy over
let htmlContent = await fs.readFile(clientHtmlSrc, 'utf-8')
htmlContent = htmlContent.replace('{jsFile}', jsFile)
htmlContent = htmlContent.replace('{timestamp}', Date.now())
await fs.writeFile(clientHtmlDest, htmlContent)
})
},
},
],
})
if (dev) {
await clientCtx.watch()
} else {
await clientCtx.rebuild()
}
}
/**
* Build Server
*/
let spawn
{
const serverCtx = await esbuild.context({
entryPoints: ['src/server/index.js'],
outfile: 'build/index.js',
platform: 'node',
format: 'esm',
bundle: true,
treeShaking: true,
minify: false,
sourcemap: true,
packages: 'external',
define: {
'process.env.CLIENT': 'false',
'process.env.SERVER': 'true',
},
plugins: [
{
name: 'server-finalize-plugin',
setup(build) {
build.onEnd(async result => {
// copy over physx wasm
const physxWasmSrc = path.join(rootDir, 'src/server/physx/physx-js-webidl.wasm')
const physxWasmDest = path.join(rootDir, 'build/physx-js-webidl.wasm')
await fs.copy(physxWasmSrc, physxWasmDest)
// start the server or stop here
if (dev) {
// (re)start server
spawn?.kill('SIGTERM')
spawn = fork(path.join(rootDir, 'build/index.js'))
} else {
process.exit(1)
}
})
},
},
],
loader: {},
})
if (dev) {
await serverCtx.watch()
} else {
await serverCtx.rebuild()
}
}