1- import { resolve } from "node:path" ;
1+ import { readdir , unlink } from "node:fs/promises" ;
2+ import { basename , dirname , join , resolve } from "node:path" ;
23import process from "node:process" ;
34import { fileURLToPath } from "node:url" ;
45
56import chokidar from "chokidar" ;
67import { context } from "esbuild" ;
78import svelte from "esbuild-svelte" ;
9+ import { sveltePreprocess } from "svelte-preprocess" ;
810
911/**
1012 * Create a debounced function.
@@ -22,16 +24,22 @@ function debounce(func: () => void, wait: number): () => void {
2224 } ;
2325}
2426
27+ const filename = fileURLToPath ( import . meta. url ) ;
28+ const outdir = join ( dirname ( filename ) , ".." , "src" , "fava" , "static" ) ;
29+ const entryPoints = [ join ( dirname ( filename ) , "src" , "app.ts" ) ] ;
30+
2531/**
2632 * Build the frontend using esbuild.
2733 * @param dev - Whether to generate sourcemaps and watch for changes.
2834 */
29- async function runBuild ( dev : boolean ) {
35+ async function run_build ( dev : boolean ) {
3036 const ctx = await context ( {
31- entryPoints : [ "src/main.ts" ] ,
37+ entryPoints,
38+ outdir,
3239 format : "esm" ,
3340 bundle : true ,
34- outfile : "../src/fava/static/app.js" ,
41+ // splitting: true, - not used yet
42+ metafile : true ,
3543 conditions : dev ? [ "development" ] : [ "production" ] ,
3644 external : [ "fs/promises" , "module" ] , // for web-tree-sitter
3745 resolveExtensions : [ ] , // enforce explicit extensions
@@ -43,13 +51,28 @@ async function runBuild(dev: boolean) {
4351 plugins : [
4452 svelte ( {
4553 compilerOptions : { dev, runes : true } ,
54+ // Needed until sourcemaps in svelte are fixed, see e.g.
55+ // https://github.com/sveltejs/svelte/issues/17003
56+ preprocess : sveltePreprocess ( ) ,
4657 } ) ,
4758 ] ,
48- sourcemap : dev ,
59+ sourcemap : true ,
4960 target : "esnext" ,
5061 } ) ;
5162 console . log ( "starting build" ) ;
52- await ctx . rebuild ( ) ;
63+ const result = await ctx . rebuild ( ) ;
64+
65+ // Clean all files in outdir except the ones from this build and favicon.ico
66+ const to_keep = new Set (
67+ Object . keys ( result . metafile . outputs ) . map ( ( p ) => basename ( p ) ) ,
68+ ) ;
69+ to_keep . add ( "favicon.ico" ) ;
70+ const outdir_files = await readdir ( outdir ) ;
71+ for ( const to_delete of outdir_files . filter ( ( f ) => ! to_keep . has ( f ) ) ) {
72+ console . log ( "Cleaning up " , to_delete ) ;
73+ await unlink ( join ( outdir , to_delete ) ) ;
74+ }
75+
5376 console . log ( "finished build" ) ;
5477
5578 if ( ! dev ) {
@@ -79,13 +102,12 @@ async function runBuild(dev: boolean) {
79102 }
80103}
81104
82- const filename = fileURLToPath ( import . meta. url ) ;
83105const is_main = resolve ( process . argv [ 1 ] ?? "" ) === filename ;
84106
85107if ( is_main ) {
86108 const watch = process . argv . includes ( "--watch" ) ;
87109
88- runBuild ( watch ) . catch ( ( e : unknown ) => {
110+ run_build ( watch ) . catch ( ( e : unknown ) => {
89111 console . error ( e ) ;
90112 } ) ;
91113}
0 commit comments