mirror of
https://github.com/czhu12/canine.git
synced 2025-12-16 16:35:10 -06:00
105 lines
2.9 KiB
JavaScript
105 lines
2.9 KiB
JavaScript
#!/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. Requires a PORT to listen on. Defaults to 3200 but can be specified with PORT env var
|
|
//
|
|
// 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
|
|
"./config/locales/**/*.yml",
|
|
]
|
|
const config = {
|
|
absWorkingDir: path.join(process.cwd(), "app/javascript"),
|
|
bundle: true,
|
|
entryPoints: 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 || 3200)
|
|
console.log(`Esbuild is listening on port ${port}`)
|
|
const context = await esbuild.context({
|
|
...config,
|
|
banner: {
|
|
js: `
|
|
(() => {
|
|
if (typeof EventSource !== 'undefined') {
|
|
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")) {
|
|
let context = await esbuild.context({...config, logLevel: 'info'})
|
|
context.watch()
|
|
} else {
|
|
esbuild.build(config)
|
|
}
|