enso/app/ide-desktop/lib/content/watch.ts
2023-06-19 01:02:08 +02:00

68 lines
2.4 KiB
TypeScript

/** @file File watch and compile service. */
import * as path from 'node:path'
import * as url from 'node:url'
import * as esbuild from 'esbuild'
import * as portfinder from 'portfinder'
import chalk from 'chalk'
import * as bundler from './esbuild-config'
import * as dashboardBundler from '../dashboard/esbuild-config'
// =================
// === Constants ===
// =================
/** The path of this file. */
const THIS_PATH = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)))
const PORT = 8080
const HTTP_STATUS_OK = 200
// ===============
// === Watcher ===
// ===============
/** Starts the esbuild watcher. */
async function watch() {
const dashboardOpts = dashboardBundler.bundleOptions()
const dashboardBuilder = await esbuild.context(dashboardOpts)
// We do not need to serve the dashboard as it outputs to the same directory.
// It will not rebuild on request, but it is not intended to rebuild on request anyway.
// This MUST be called before `builder.watch()` as `tailwind.css` must be generated
// before the copy plugin runs.
await dashboardBuilder.watch()
const opts = bundler.bundlerOptions(
bundler.argumentsFromEnv({
devMode: true,
supportsLocalBackend: true,
supportsDeepLinks: false,
})
)
opts.pure.splice(opts.pure.indexOf('assert'), 1)
;(opts.inject = opts.inject ?? []).push(path.resolve(THIS_PATH, '..', '..', 'debugGlobals.ts'))
opts.define.REDIRECT_OVERRIDE = JSON.stringify('http://localhost:8080')
// This is safe as this entry point is statically known.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const serviceWorkerEntryPoint = opts.entryPoints.find(
entryPoint => entryPoint.out === 'serviceWorker'
)!
serviceWorkerEntryPoint.in = path.resolve(THIS_PATH, 'src', 'devServiceWorker.ts')
const builder = await esbuild.context(opts)
await builder.watch()
await builder.serve({
port: await portfinder.getPortPromise({ port: PORT }),
servedir: opts.outdir,
/** This function is called on every request.
* It is used here to show an error if the file to serve was not found. */
onRequest(args) {
if (args.status !== HTTP_STATUS_OK) {
console.error(
chalk.red(`HTTP error ${args.status} when serving path '${args.path}'.`)
)
}
},
})
}
void watch()