From 8c51388edf8137ac9974336ab582fe632317309c Mon Sep 17 00:00:00 2001 From: Soroosh Taefi Date: Wed, 3 Apr 2024 17:15:37 +0300 Subject: [PATCH] fix: request full-reload only when file-routes.json is added/changed (#2289) * fix: full-reload only when file-routes.json is added/changed Fixes: #2277 --- packages/ts/file-router/src/vite-plugin.ts | 9 ++- .../test/vite-plugin/vite-plugin.spec.ts | 59 +++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 packages/ts/file-router/test/vite-plugin/vite-plugin.spec.ts diff --git a/packages/ts/file-router/src/vite-plugin.ts b/packages/ts/file-router/src/vite-plugin.ts index 2d4b0cd3e6..8fbecbaa0a 100644 --- a/packages/ts/file-router/src/vite-plugin.ts +++ b/packages/ts/file-router/src/vite-plugin.ts @@ -86,12 +86,15 @@ export default function vitePluginFileSystemRouter({ const changeListener = (file: string): void => { if (!file.startsWith(dir)) { + if (file === fileURLToPath(runtimeUrls.json)) { + server.hot.send({ type: 'full-reload' }); + } return; } - generateRuntimeFiles(_viewsDir, runtimeUrls, extensions, _logger) - .then(() => server.hot.send({ type: 'full-reload' })) - .catch((e: unknown) => _logger.error(String(e))); + generateRuntimeFiles(_viewsDir, runtimeUrls, extensions, _logger).catch((e: unknown) => + _logger.error(String(e)), + ); }; server.watcher.on('add', changeListener); diff --git a/packages/ts/file-router/test/vite-plugin/vite-plugin.spec.ts b/packages/ts/file-router/test/vite-plugin/vite-plugin.spec.ts new file mode 100644 index 0000000000..e206d02ddf --- /dev/null +++ b/packages/ts/file-router/test/vite-plugin/vite-plugin.spec.ts @@ -0,0 +1,59 @@ +import { EventEmitter } from 'node:events'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { expect, use } from '@esm-bundle/chai'; +import chaiAsPromised from 'chai-as-promised'; +import sinon from 'sinon'; +import sinonChai from 'sinon-chai'; +import vitePluginFileSystemRouter from '../../src/vite-plugin'; + +use(chaiAsPromised); +use(sinonChai); + +describe('@vaadin/hilla-file-router', () => { + describe('vite-plugin', () => { + const rootDir = pathToFileURL('/path/to/project/'); + const outDir = new URL('dist/', rootDir); + const viewsDir = new URL('frontend/views/', rootDir); + const generatedDir = new URL('frontend/generated/', rootDir); + const watcher = new EventEmitter(); + const mockServer = { + hot: { + send: sinon.spy(), + }, + watcher, + }; + const plugin = vitePluginFileSystemRouter({ isDevMode: true }); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error: the configResolved method could be either a function or an object. + plugin.configResolved({ + logger: { info: sinon.spy() }, + root: fileURLToPath(rootDir), + build: { outDir: fileURLToPath(outDir) }, + }); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error: the configResolved method could be either a function or an object. + plugin.configureServer(mockServer); + + beforeEach(() => { + sinon.resetHistory(); + }); + + it('should send full-reload only when file-routes.json is added', () => { + expect(mockServer.hot.send).to.not.be.called; + mockServer.watcher.emit('add', fileURLToPath(new URL('file-routes.json', generatedDir))); + expect(mockServer.hot.send).to.be.calledWith({ type: 'full-reload' }); + }); + + it('should send full-reload only when file-routes.json changes', () => { + expect(mockServer.hot.send).to.not.be.called; + mockServer.watcher.emit('change', fileURLToPath(new URL('file-routes.json', generatedDir))); + expect(mockServer.hot.send).to.be.calledWith({ type: 'full-reload' }); + }); + + it('should not send full-reload when other files change', () => { + expect(mockServer.hot.send).to.not.be.called; + mockServer.watcher.emit('change', fileURLToPath(new URL('file.tsx', viewsDir))); + expect(mockServer.hot.send).to.not.be.called; + }); + }); +});