Skip to content

Commit

Permalink
Add example esbuild config with esbuild-rails and watch / reload flags
Browse files Browse the repository at this point in the history
  • Loading branch information
excid3 authored Jan 16, 2023
1 parent d473874 commit 8ee570a
Showing 1 changed file with 97 additions and 0 deletions.
97 changes: 97 additions & 0 deletions examples/esbuild.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/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",
"administrate.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: 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")) {
let context = await esbuild.context({...config, logLevel: 'info'})
context.watch()
} else {
esbuild.build(config)
}

0 comments on commit 8ee570a

Please sign in to comment.