From c695053c2619531259eefb80bdfc1388a3b0655d Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 17:59:21 +0200 Subject: [PATCH 01/10] feat(watcher): use `@parcel/watcher` to watch entire app directory --- package.json | 1 + pnpm-lock.yaml | 132 ++++++++++++++++++++++++++++++++++++++++++++++--- src/_utils.ts | 5 +- src/watch.ts | 22 +++++++-- 4 files changed, 145 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index b77f787..ed0904b 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "test": "pnpm lint && vitest run --coverage" }, "dependencies": { + "@parcel/watcher": "^2.2.0", "citty": "^0.1.2", "clipboardy": "^3.0.0", "consola": "^3.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1eb1d4c..cf11d8a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@parcel/watcher': + specifier: ^2.2.0 + version: 2.2.0 citty: specifier: ^0.1.2 version: 0.1.2 @@ -617,6 +620,117 @@ packages: fastq: 1.15.0 dev: true + /@parcel/watcher-android-arm64@2.2.0: + resolution: {integrity: sha512-nU2wh00CTQT9rr1TIKTjdQ9lAGYpmz6XuKw0nAwAN+S2A5YiD55BK1u+E5WMCT8YOIDe/n6gaj4o/Bi9294SSQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-darwin-arm64@2.2.0: + resolution: {integrity: sha512-cJl0UZDcodciy3TDMomoK/Huxpjlkkim3SyMgWzjovHGOZKNce9guLz2dzuFwfObBFCjfznbFMIvAZ5syXotYw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-darwin-x64@2.2.0: + resolution: {integrity: sha512-QI77zxaGrCV1StKcoRYfsUfmUmvPMPfQrubkBBy5XujV2fwaLgZivQOTQMBgp5K2+E19u1ufpspKXAPqSzpbyg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm-glibc@2.2.0: + resolution: {integrity: sha512-I2GPBcAXazPzabCmfsa3HRRW+MGlqxYd8g8RIueJU+a4o5nyNZDz0CR1cu0INT0QSQXEZV7w6UE8Hz9CF8u3Pg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm64-glibc@2.2.0: + resolution: {integrity: sha512-St5mlfp+2lS9AmgixUqfwJa/DwVmTCJxC1HcOubUTz6YFOKIlkHCeUa1Bxi4E/tR/HSez8+heXHL8HQkJ4Bd8g==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm64-musl@2.2.0: + resolution: {integrity: sha512-jS+qfhhoOBVWwMLP65MaG8xdInMK30pPW8wqTCg2AAuVJh5xepMbzkhHJ4zURqHiyY3EiIRuYu4ONJKCxt8iqA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-x64-glibc@2.2.0: + resolution: {integrity: sha512-xJvJ7R2wJdi47WZBFS691RDOWvP1j/IAs3EXaWVhDI8FFITbWrWaln7KoNcR0Y3T+ZwimFY/cfb0PNht1q895g==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-x64-musl@2.2.0: + resolution: {integrity: sha512-D+NMpgr23a+RI5mu8ZPKWy7AqjBOkURFDgP5iIXXEf/K3hm0jJ3ogzi0Ed2237B/CdYREimCgXyeiAlE/FtwyA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-win32-arm64@2.2.0: + resolution: {integrity: sha512-z225cPn3aygJsyVUOWwfyW+fY0Tvk7N3XCOl66qUPFxpbuXeZuiuuJemmtm8vxyqa3Ur7peU/qJxrpC64aeI7Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-win32-x64@2.2.0: + resolution: {integrity: sha512-JqGW0RJ61BkKx+yYzIURt9s53P7xMVbv0uxYPzAXLBINGaFmkIKSuUPyBVfy8TMbvp93lvF4SPBNDzVRJfvgOw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher@2.2.0: + resolution: {integrity: sha512-71S4TF+IMyAn24PK4KSkdKtqJDR3zRzb0HE3yXpacItqTM7XfF2f5q9NEGLEVl0dAaBAGfNwDCjH120y25F6Tg==} + engines: {node: '>= 10.0.0'} + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.5 + node-addon-api: 7.0.0 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.2.0 + '@parcel/watcher-darwin-arm64': 2.2.0 + '@parcel/watcher-darwin-x64': 2.2.0 + '@parcel/watcher-linux-arm-glibc': 2.2.0 + '@parcel/watcher-linux-arm64-glibc': 2.2.0 + '@parcel/watcher-linux-arm64-musl': 2.2.0 + '@parcel/watcher-linux-x64-glibc': 2.2.0 + '@parcel/watcher-linux-x64-musl': 2.2.0 + '@parcel/watcher-win32-arm64': 2.2.0 + '@parcel/watcher-win32-x64': 2.2.0 + dev: false + /@pkgr/utils@2.4.2: resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1152,7 +1266,6 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: true /browserslist@4.21.10: resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} @@ -1467,6 +1580,12 @@ packages: resolution: {integrity: sha512-FJ9RDpf3GicEBvzI3jxc2XhHzbqD8p4ANw/1kPsFBfTvP1b7Gn/Lg1vO7R9J4IVgoMbyUmFrFGZafJ1hPZpvlg==} dev: true + /detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + dev: false + /diff-sequences@29.4.3: resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2057,7 +2176,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: true /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} @@ -2509,14 +2627,12 @@ packages: /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} @@ -2545,7 +2661,6 @@ packages: /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} @@ -2816,7 +2931,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} @@ -2940,6 +3054,10 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true + /node-addon-api@7.0.0: + resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} + dev: false + /node-fetch-native@1.2.0: resolution: {integrity: sha512-5IAMBTl9p6PaAjYCnMv5FmqIF6GcZnawAVnzaCG0rX2aYZJ4CxEkZNtVPuTRug7fL7wyM5BQYTlAzcyMPi6oTQ==} dev: true @@ -3182,7 +3300,6 @@ packages: /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: true /pkg-types@1.0.3: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} @@ -3653,7 +3770,6 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - dev: true /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} diff --git a/src/_utils.ts b/src/_utils.ts index 4ef5ca3..3f9011f 100644 --- a/src/_utils.ts +++ b/src/_utils.ts @@ -84,7 +84,7 @@ export async function createImporter(input: string, _cwd?: string) { input = `./${input}`; } - const entry = _jitiRequire.resolve(resolve(cwd, input)); + const entry = _jitiRequire.resolve(input); const _import = () => { const r = _jitiRequire(input); @@ -92,8 +92,9 @@ export async function createImporter(input: string, _cwd?: string) { }; return { + cwd, + relative: (path: string) => relative(cwd, path), entry, - relativeEntry: relative(cwd, entry), import: _import, }; } diff --git a/src/watch.ts b/src/watch.ts index e498c15..72343c1 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -1,6 +1,6 @@ import type { RequestListener } from "node:http"; -import { watch } from "node:fs"; import { consola } from "consola"; +import { dirname } from "pathe"; import type { Listener, ListenOptions, WatchOptions } from "./types"; import { listen } from "./listen"; import { createImporter } from "./_utils"; @@ -21,8 +21,18 @@ export async function listenAndWatch( resolveHandle(); - const watcher = await watch(importer.entry, () => { - logger.info(`\`${importer.relativeEntry}\` changed, Reloading...`); + // https://github.com/parcel-bundler/watcher + const { subscribe } = await import("@parcel/watcher").then( + (r) => r.default || r, + ); + + const entryDir = dirname(importer.entry); + const watcher = await subscribe(entryDir, (_error, events) => { + logger.log( + `🔃 ${events + .map((e) => `\`./${importer.relative(e.path)}\` ${e.type}d`) + .join(", ")}. Reloading server...`, + ); resolveHandle(); }); @@ -30,11 +40,13 @@ export async function listenAndWatch( return handle(...args); }, options); - logger.info(`Watching \`${importer.relativeEntry}\` for changes.`); + logger.log(`👀 Watching \`./${importer.relative(entryDir)}\` for changes.`); const _close = listenter.close; listenter.close = async () => { - watcher.close(); + await watcher.unsubscribe().catch((error) => { + logger.error(error); + }); await _close(); }; From 81f22644e36d98c95d510f62a7ec0a6324e3963e Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 18:04:10 +0200 Subject: [PATCH 02/10] ocd: move path to the end --- src/watch.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/watch.ts b/src/watch.ts index 72343c1..da02b18 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -28,10 +28,13 @@ export async function listenAndWatch( const entryDir = dirname(importer.entry); const watcher = await subscribe(entryDir, (_error, events) => { + if (events.length === 0) { + return; + } logger.log( - `🔃 ${events + `🔃 Reloading server... (${events .map((e) => `\`./${importer.relative(e.path)}\` ${e.type}d`) - .join(", ")}. Reloading server...`, + .join(", ")})`, ); resolveHandle(); }); From 94800261701fa63e33ac72574c64d86cc1876482 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 18:30:38 +0200 Subject: [PATCH 03/10] improve error handling and experience --- playground/app.ts | 2 +- src/_utils.ts | 1 + src/watch.ts | 84 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/playground/app.ts b/playground/app.ts index 8efaf75..80279eb 100644 --- a/playground/app.ts +++ b/playground/app.ts @@ -4,5 +4,5 @@ export const app = createApp(); app.use( "/", - eventHandler(() => ({ hello: "world!" })), + eventHandler(() => ({ hello: "world!!" })), ); diff --git a/src/_utils.ts b/src/_utils.ts index 3f9011f..abe6bc5 100644 --- a/src/_utils.ts +++ b/src/_utils.ts @@ -94,6 +94,7 @@ export async function createImporter(input: string, _cwd?: string) { return { cwd, relative: (path: string) => relative(cwd, path), + formateRelative: (path: string) => `\`./${relative(cwd, path)}\``, entry, import: _import, }; diff --git a/src/watch.ts b/src/watch.ts index da02b18..8352ddb 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -1,6 +1,7 @@ import type { RequestListener } from "node:http"; import { consola } from "consola"; import { dirname } from "pathe"; +import type { AsyncSubscription } from "@parcel/watcher"; import type { Listener, ListenOptions, WatchOptions } from "./types"; import { listen } from "./listen"; import { createImporter } from "./_utils"; @@ -10,48 +11,83 @@ export async function listenAndWatch( options: Partial = {}, ): Promise { const logger = options.logger || consola.withTag("listhen"); + let watcher: AsyncSubscription; // eslint-disable-line prefer-const + let handle: RequestListener | undefined; + let error: undefined | unknown; - let handle: RequestListener; + // Initialize listener + const listenter = await listen((req, res) => { + if (error) { + res.end((error as Error)?.stack || error.toString()); + } else if (handle) { + return handle(req, res); + } else { + res.end("Please wait for the server to load."); + } + }, options); - const importer = await createImporter(input); + // Hook close event to stop watcher too + const _close = listenter.close; + listenter.close = async () => { + if (watcher) { + await watcher.unsubscribe().catch((error) => { + logger.error(error); + }); + } + await _close(); + }; + // Initialize resolver + let loadTime = 0; + const importer = await createImporter(input); const resolveHandle = async () => { - handle = await importer.import(); + const start = Date.now(); + try { + handle = await importer.import(); + error = undefined; + } catch (_error) { + error = _error; + } + loadTime = Date.now() - start; }; - resolveHandle(); + // Resolve handle once + logger.info( + `Loading server entry ${importer.formateRelative(importer.entry)}`, + ); + resolveHandle().then(() => { + if (error) { + logger.error(error); + } else { + logger.log(`🚀 Server initialized in ${loadTime}ms.`); + } + }); + // Start watcher // https://github.com/parcel-bundler/watcher const { subscribe } = await import("@parcel/watcher").then( (r) => r.default || r, ); const entryDir = dirname(importer.entry); - const watcher = await subscribe(entryDir, (_error, events) => { + watcher = await subscribe(entryDir, (_error, events) => { if (events.length === 0) { return; } - logger.log( - `🔃 Reloading server... (${events - .map((e) => `\`./${importer.relative(e.path)}\` ${e.type}d`) - .join(", ")})`, - ); - resolveHandle(); + resolveHandle().then(() => { + const eventsString = events + .map((e) => `${importer.formateRelative(e.path)} ${e.type}d`) + .join(", "); + logger.log(`${eventsString}. Reloading server...`); + if (error) { + logger.error(error); + } else { + logger.log(`🔃 Server Reloaded in ${loadTime}ms.`); + } + }); }); - const listenter = await listen((...args) => { - return handle(...args); - }, options); - - logger.log(`👀 Watching \`./${importer.relative(entryDir)}\` for changes.`); - - const _close = listenter.close; - listenter.close = async () => { - await watcher.unsubscribe().catch((error) => { - logger.error(error); - }); - await _close(); - }; + logger.log(`👀 Watching ${importer.formateRelative(entryDir)} for changes.`); return listenter; } From a9caff2ea7f1b052b6b57ec1281630546a50aff2 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 18:53:04 +0200 Subject: [PATCH 04/10] add error template --- src/watch.ts | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/watch.ts b/src/watch.ts index 8352ddb..f72e18a 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -1,4 +1,4 @@ -import type { RequestListener } from "node:http"; +import type { RequestListener, ServerResponse } from "node:http"; import { consola } from "consola"; import { dirname } from "pathe"; import type { AsyncSubscription } from "@parcel/watcher"; @@ -18,11 +18,15 @@ export async function listenAndWatch( // Initialize listener const listenter = await listen((req, res) => { if (error) { - res.end((error as Error)?.stack || error.toString()); + res.setHeader("Content-Type", "text/html"); + return res.end(errorTemplate(error.toString(), (error as Error)?.stack)); } else if (handle) { return handle(req, res); } else { - res.end("Please wait for the server to load."); + res.setHeader("Content-Type", "text/html"); + return res.end( + `

Server is loading...

`, + ); } }, options); @@ -91,3 +95,26 @@ export async function listenAndWatch( return listenter; } + +function errorTemplate(message: string, stack?: string) { + return ` + + + Server Error + + + + + +
+
+ +
Server Error
+
${message}
${stack}
+
+
+ + `; +} From 0ba79bcc0849d019ffb11a9db7daa57248309c7b Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 19:36:23 +0200 Subject: [PATCH 05/10] add default ignore --- src/watch.ts | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/watch.ts b/src/watch.ts index f72e18a..d48909b 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -74,22 +74,28 @@ export async function listenAndWatch( ); const entryDir = dirname(importer.entry); - watcher = await subscribe(entryDir, (_error, events) => { - if (events.length === 0) { - return; - } - resolveHandle().then(() => { - const eventsString = events - .map((e) => `${importer.formateRelative(e.path)} ${e.type}d`) - .join(", "); - logger.log(`${eventsString}. Reloading server...`); - if (error) { - logger.error(error); - } else { - logger.log(`🔃 Server Reloaded in ${loadTime}ms.`); + watcher = await subscribe( + entryDir, + (_error, events) => { + if (events.length === 0) { + return; } - }); - }); + resolveHandle().then(() => { + const eventsString = events + .map((e) => `${importer.formateRelative(e.path)} ${e.type}d`) + .join(", "); + logger.log(`${eventsString}. Reloading server...`); + if (error) { + logger.error(error); + } else { + logger.log(`🔃 Server Reloaded in ${loadTime}ms.`); + } + }); + }, + { + ignore: ["**/.git/**", "**/node_modules/**", "**/dist/**"], + }, + ); logger.log(`👀 Watching ${importer.formateRelative(entryDir)} for changes.`); From 39b8d21e6a979f49534648aa965f3e3f0e2b6f38 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 19:37:03 +0200 Subject: [PATCH 06/10] allow overriding ignore with options --- src/types.ts | 1 + src/watch.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 9e581a0..0d3d246 100644 --- a/src/types.ts +++ b/src/types.ts @@ -34,6 +34,7 @@ export interface WatchOptions { cwd: string; entry: string; logger: ConsolaInstance; + ignore: string[]; } export interface ShowURLOptions { diff --git a/src/watch.ts b/src/watch.ts index d48909b..3b0214a 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -1,4 +1,4 @@ -import type { RequestListener, ServerResponse } from "node:http"; +import type { RequestListener } from "node:http"; import { consola } from "consola"; import { dirname } from "pathe"; import type { AsyncSubscription } from "@parcel/watcher"; @@ -93,7 +93,11 @@ export async function listenAndWatch( }); }, { - ignore: ["**/.git/**", "**/node_modules/**", "**/dist/**"], + ignore: options.ignore || [ + "**/.git/**", + "**/node_modules/**", + "**/dist/**", + ], }, ); From 3e7845891a9b71adbefb2206d49f527d0821e6b3 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 19:47:30 +0200 Subject: [PATCH 07/10] improve formatting --- src/watch.ts | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/watch.ts b/src/watch.ts index 3b0214a..2a79f63 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -1,5 +1,6 @@ import type { RequestListener } from "node:http"; import { consola } from "consola"; +import { colors } from "consola/utils"; import { dirname } from "pathe"; import type { AsyncSubscription } from "@parcel/watcher"; import type { Listener, ListenOptions, WatchOptions } from "./types"; @@ -56,14 +57,18 @@ export async function listenAndWatch( }; // Resolve handle once - logger.info( - `Loading server entry ${importer.formateRelative(importer.entry)}`, + logger.log( + colors.gray( + `🚀 Loading server entry ${importer.formateRelative(importer.entry)}`, + ), ); resolveHandle().then(() => { if (error) { logger.error(error); } else { - logger.log(`🚀 Server initialized in ${loadTime}ms.`); + logger.log( + colors.gray(`✅ Server initialized in ${colors.bold(loadTime)}ms.`), + ); } }); @@ -82,13 +87,18 @@ export async function listenAndWatch( } resolveHandle().then(() => { const eventsString = events - .map((e) => `${importer.formateRelative(e.path)} ${e.type}d`) + .map( + (e) => + `${colors.cyan(`./${importer.relative(e.path)}`)} ${e.type}d`, + ) .join(", "); - logger.log(`${eventsString}. Reloading server...`); + logger.log(colors.gray(`🔃 Reloading server... (${eventsString})`)); if (error) { logger.error(error); } else { - logger.log(`🔃 Server Reloaded in ${loadTime}ms.`); + logger.log( + colors.gray(`✅ Server reloaded in ${colors.bold(loadTime)}ms.`), + ); } }); }, @@ -101,7 +111,13 @@ export async function listenAndWatch( }, ); - logger.log(`👀 Watching ${importer.formateRelative(entryDir)} for changes.`); + logger.log( + colors.gray( + `👀 Watching ${colors.cyan( + "./" + importer.relative(entryDir), + )} for changes.`, + ), + ); return listenter; } From 01929b97ac27768032b1d39d8e2852a49fb282e5 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 19:57:34 +0200 Subject: [PATCH 08/10] streamline logs --- src/watch.ts | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/watch.ts b/src/watch.ts index 2a79f63..047ef9b 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -1,6 +1,5 @@ import type { RequestListener } from "node:http"; import { consola } from "consola"; -import { colors } from "consola/utils"; import { dirname } from "pathe"; import type { AsyncSubscription } from "@parcel/watcher"; import type { Listener, ListenOptions, WatchOptions } from "./types"; @@ -58,17 +57,13 @@ export async function listenAndWatch( // Resolve handle once logger.log( - colors.gray( - `🚀 Loading server entry ${importer.formateRelative(importer.entry)}`, - ), + `🚀 Loading server entry ${importer.formateRelative(importer.entry)}`, ); resolveHandle().then(() => { if (error) { logger.error(error); } else { - logger.log( - colors.gray(`✅ Server initialized in ${colors.bold(loadTime)}ms.`), - ); + logger.success(` Server initialized in ${loadTime}ms`); } }); @@ -87,18 +82,13 @@ export async function listenAndWatch( } resolveHandle().then(() => { const eventsString = events - .map( - (e) => - `${colors.cyan(`./${importer.relative(e.path)}`)} ${e.type}d`, - ) + .map((e) => `${importer.formateRelative(e.path)} ${e.type}d`) .join(", "); - logger.log(colors.gray(`🔃 Reloading server... (${eventsString})`)); + logger.start(` Reloading server (${eventsString})`); if (error) { logger.error(error); } else { - logger.log( - colors.gray(`✅ Server reloaded in ${colors.bold(loadTime)}ms.`), - ); + logger.success(` Server reloaded in ${loadTime}ms`); } }); }, @@ -111,13 +101,7 @@ export async function listenAndWatch( }, ); - logger.log( - colors.gray( - `👀 Watching ${colors.cyan( - "./" + importer.relative(entryDir), - )} for changes.`, - ), - ); + logger.log(`👀 Watching ${importer.formateRelative(entryDir)} for changes`); return listenter; } From 7691a22927e72401dd21f9442c9e13d337668197 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 20:08:28 +0200 Subject: [PATCH 09/10] improve error display --- playground/app.ts | 2 +- src/watch.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/playground/app.ts b/playground/app.ts index 80279eb..0066115 100644 --- a/playground/app.ts +++ b/playground/app.ts @@ -1,6 +1,6 @@ import { createApp, eventHandler } from "h3"; -export const app = createApp(); +export const app = createApp(; app.use( "/", diff --git a/src/watch.ts b/src/watch.ts index 047ef9b..c939687 100644 --- a/src/watch.ts +++ b/src/watch.ts @@ -50,6 +50,17 @@ export async function listenAndWatch( handle = await importer.import(); error = undefined; } catch (_error) { + try { + const cwd = process.cwd(); + const InternalStackRe = + /jiti|node:internal|citty|listhen|listenAndWatch/; + (_error as Error).stack = (_error as Error) + .stack!.split("\n") + .slice(1) + .map((l) => l.replace(cwd, ".")) + .filter((l) => !InternalStackRe.test(l)) + .join("\n"); + } catch {} error = _error; } loadTime = Date.now() - start; @@ -106,7 +117,7 @@ export async function listenAndWatch( return listenter; } -function errorTemplate(message: string, stack?: string) { +function errorTemplate(message: string, stack = "") { return ` @@ -114,7 +125,49 @@ function errorTemplate(message: string, stack?: string) { From 19ed49a8fe39bd0097c5a41f266a46deb9a7185f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 2 Aug 2023 20:08:39 +0200 Subject: [PATCH 10/10] fix my app! --- playground/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/app.ts b/playground/app.ts index 0066115..80279eb 100644 --- a/playground/app.ts +++ b/playground/app.ts @@ -1,6 +1,6 @@ import { createApp, eventHandler } from "h3"; -export const app = createApp(; +export const app = createApp(); app.use( "/",