-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
esbuild.config.mjs
96 lines (87 loc) · 2.61 KB
/
esbuild.config.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
#!/usr/bin/env node
// Esbuild is configured with 3 modes:
//
// `yarn build` - Build JavaScript and exit
// `yarn build --watch` - Rebuild JavaScript on change
// `yarn build --reload` - Reloads page when views, JavaScript, or stylesheets change
//
// Minify is enabled when "RAILS_ENV=production"
// Sourcemaps are enabled in non-production environments
import * as esbuild from 'esbuild'
import path from 'path'
import rails from 'esbuild-rails'
import chokidar from 'chokidar'
import http from 'http'
import { setTimeout } from 'timers/promises'
const clients = []
const entryPoints = [
'application.js'
]
const watchDirectories = [
'./app/javascript/**/*.js',
'./app/views/**/*.html.erb',
'./app/assets/builds/**/*.css' // Wait for cssbundling changes
]
const config = {
absWorkingDir: path.join(process.cwd(), 'app/javascript'),
bundle: true,
entryPoints,
minify: process.env.RAILS_ENV === 'production',
outdir: path.join(process.cwd(), 'app/assets/builds'),
plugins: [rails()],
sourcemap: process.env.RAILS_ENV !== 'production'
}
async function buildAndReload () {
// Foreman & Overmind assign a separate PORT for each process
const port = parseInt(process.env.PORT)
const context = await esbuild.context({
...config,
banner: {
js: ` (() => new EventSource("http://localhost:${port}").onmessage = () => location.reload())();`
}
})
// Reload uses an HTTP server as an even stream to reload the browser
http
.createServer((req, res) => {
return clients.push(
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Access-Control-Allow-Origin': '*',
Connection: 'keep-alive'
})
)
})
.listen(port)
await context.rebuild()
console.log('[reload] initial build succeeded')
let ready = false
chokidar
.watch(watchDirectories)
.on('ready', () => {
console.log('[reload] ready')
ready = true
})
.on('all', async (event, path) => {
if (ready === false) return
if (path.includes('javascript')) {
try {
await setTimeout(20)
await context.rebuild()
console.log('[reload] build succeeded')
} catch (error) {
console.error('[reload] build failed', error)
}
}
clients.forEach((res) => res.write('data: update\n\n'))
clients.length = 0
})
}
if (process.argv.includes('--reload')) {
buildAndReload()
} else if (process.argv.includes('--watch')) {
const context = await esbuild.context({ ...config, logLevel: 'info' })
context.watch()
} else {
esbuild.build(config)
}