Using Chokidar with Esbuild To Rebuild On Change
This month I was migrating from Webpacker to ESBuild using JSBundling in a client's Ruby on Rails project, since, they were using Stimulus & a couple of Javascript dependencies in the project, the migration went smoothly.
However, I realised that ESBuild doesn't watch for changes in the root project instead it only listens to the files mentioned in `entryPoints` config. This doesn't make it an ideal DX (developer experience), so I decided to dig deeper on how to get this experience right.
I found an issue on ESBuild repo a lot of folks have shared their approach to solve it. I picked the one that felt right for our use case, tweaked it a little bit to get what I want & kept is as simple as I could. Here is what I ended up with
const path = require('path')
const chokidar = require('chokidar')
const esbuild = require("esbuild")
const watchDirectories = [
"./app/javascript/**/*.js",
"./app/views/**/*.html.erb",
]
const config = {
entryPoints: ["application.js", "admin.js"],
bundle: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: process.argv.includes("--watch"),
sourcemap: process.argv.includes("--watch"),
incremental: process.argv.includes("--watch"),
plugins: [],
}
if (process.argv.includes("--watch")) {
(async () => {
const result = await esbuild.build(config);
chokidar.watch(watchDirectories).on('all', (event, path) => {
console.log(`rebuilding ${path}`)
result.rebuild()
})
})();
} else {
esbuild.build(config).catch(() => process.exit(1))
}
Basically, this uses Chokidar which is a Nodejs package to watch changes on specified files. So I used a combination of Chokidar and ESBuild package to rebuild files whenever there are changes in the project, and because ESbuild is fast there isn't much waiting & overhead.