diff --git a/package.json b/package.json index 4eff27a..1c4c553 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "del-cli": "^5.1.0", "eslint": "^8.57.0", "github-label-sync": "^2.3.1", - "hot-hook": "^0.1.9", + "hot-hook": "^0.2.1", "husky": "^9.0.11", "np": "^10.0.3", "p-event": "^6.0.1", diff --git a/src/dev_server.ts b/src/dev_server.ts index 240a63c..387d98c 100644 --- a/src/dev_server.ts +++ b/src/dev_server.ts @@ -11,6 +11,7 @@ import picomatch from 'picomatch' import { relative } from 'node:path' import type tsStatic from 'typescript' import prettyHrtime from 'pretty-hrtime' +import { fileURLToPath } from 'node:url' import { type ExecaChildProcess } from 'execa' import { cliui, type Logger } from '@poppinss/cliui' import type { Watcher } from '@poppinss/chokidar-ts' @@ -168,7 +169,7 @@ export class DevServer { * Starts the HTTP server */ #startHTTPServer(port: string, mode: 'blocking' | 'nonblocking') { - const hooksArgs = { colors: ui.colors, logger: this.#logger } + const hooksArgs = { colors: this.#colors, logger: this.#logger } this.#httpServer = runNode(this.#cwd, { script: this.#scriptFile, env: { PORT: port, ...this.#options.env }, @@ -185,16 +186,16 @@ export class DevServer { * Handle Hot-Hook messages */ if (this.#isHotHookMessage(message)) { - const path = relative(this.#cwd.pathname, message.path || message.paths?.[0]!) + const path = relative(fileURLToPath(this.#cwd), message.path || message.paths?.[0]!) this.#hooks.onSourceFileChanged(hooksArgs, path) if (message.type === 'hot-hook:full-reload') { this.#clearScreen() - this.#logger.log(`${ui.colors.green('full-reload')} ${path}`) + this.#logger.log(`${this.#colors.green('full-reload')} ${path}`) this.#restartHTTPServer(port) this.#hooks.onDevServerStarted(hooksArgs) } else if (message.type === 'hot-hook:invalidated') { - this.#logger.log(`${ui.colors.green('invalidated')} ${path}`) + this.#logger.log(`${this.#colors.green('invalidated')} ${path}`) } } @@ -296,7 +297,6 @@ export class DevServer { * Handles TypeScript source file change */ async #handleSourceFileChange(action: string, port: string, relativePath: string) { - console.log({ relativePath }) await this.#hooks.onSourceFileChanged({ colors: ui.colors, logger: this.#logger }, relativePath) this.#clearScreen() diff --git a/tests/dev_server.spec.ts b/tests/dev_server.spec.ts index 326a5ad..74aabf5 100644 --- a/tests/dev_server.spec.ts +++ b/tests/dev_server.spec.ts @@ -10,6 +10,7 @@ import ts from 'typescript' import { test } from '@japa/runner' import { cliui } from '@poppinss/cliui' +import { relative, resolve } from 'node:path' import { setTimeout as sleep } from 'node:timers/promises' import { DevServer } from '../index.js' @@ -92,7 +93,7 @@ test.group('DevServer', () => { await devServer.startAndWatch(ts) cleanup(() => devServer.close()) - await sleep(100) + await sleep(1000) await fs.create('index.ts', 'foo') }).waitForDone() @@ -281,4 +282,46 @@ test.group('DevServer', () => { assert.isTrue(onDevServerStartedCalled) assert.isTrue(onSourceFileChangedCalled) }) + + test('should correctly display a relative path when a hot-hook message is received', async ({ + assert, + fs, + }) => { + await fs.createJson('tsconfig.json', { include: ['**/*'], exclude: [] }) + await fs.createJson('package.json', { type: 'module', hotHook: { boundaries: ['./app/**'] } }) + await fs.create('app/controllers/app_controller.ts', 'console.log("foo")') + await fs.create( + 'bin/server.js', + ` + import { resolve } from 'path'; + import '../app/controllers/app_controller.js'; + ` + ) + await fs.create('.env', 'PORT=3334') + + const { logger } = cliui({ mode: 'raw' }) + const devServer = new DevServer(fs.baseUrl, { + hmr: true, + nodeArgs: [], + scriptArgs: [], + }).setLogger(logger) + + await devServer.start() + await sleep(2000) + await fs.create('app/controllers/app_controller.ts', 'console.log("bar")') + await sleep(2000) + await devServer.close() + + const logMessages = logger.getLogs().map(({ message }) => message) + + const relativePath = relative( + fs.basePath, + resolve(fs.basePath, 'app/controllers/app_controller.ts') + ) + + console.log({ relativePath }) + console.log(logMessages) + const expectedMessage = `green(invalidated) ${relativePath}` + assert.isAtLeast(logMessages.filter((message) => message.includes(expectedMessage)).length, 1) + }).timeout(10_000) })