From 0a901c9affa17af44a5f9599f288f3746d37ad95 Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 14 Nov 2024 21:57:48 +0100 Subject: [PATCH 1/2] fix: restart v4 compat dev server on when config. file changes --- package.json | 1 + src/utils/layers.ts | 21 +++++++++++++---- src/utils/loader.ts | 56 +++++++++++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 0426cc0..f15eeab 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "@vuetify/loader-shared", "node:child_process", "node:fs", + "chokidar", "consola", "destr", "esbuild", diff --git a/src/utils/layers.ts b/src/utils/layers.ts index 459fcb9..72e09f9 100644 --- a/src/utils/layers.ts +++ b/src/utils/layers.ts @@ -1,5 +1,6 @@ import type { Nuxt } from '@nuxt/schema' import defu from 'defu' +import { normalize } from 'pathe' import type { FontIconSet, IconFontName, InlineModuleOptions, VuetifyModuleOptions } from '../types' import { loadVuetifyConfiguration } from './config' @@ -42,10 +43,22 @@ export async function mergeVuetifyModules(options: VuetifyModuleOptions, nuxt: N // handle vuetify configuraton files changes only in dev mode if (nuxt.options.dev && resolvedOptions.sources.length) { // we need to restart nuxt dev server when SSR is enabled: vite-node doesn't support HMR in server yet - if (nuxt.options.ssr) - resolvedOptions.sources.forEach(s => nuxt.options.watch.push(s.replace(/\\/g, '/'))) - else - resolvedOptions.sources.forEach(s => vuetifyConfigurationFilesToWatch.add(s.replace(/\\/g, '/'))) + if (nuxt.options.ssr) { + if (nuxt.options.future?.compatibilityVersion === 4) { + if (resolvedOptions.sources.length) { + resolvedOptions.sources + .map(s => s.replace(/\\/g, '/')) + .filter(s => !s.includes('/node_modules/')) + .forEach(s => vuetifyConfigurationFilesToWatch.add(s)) + } + } + else { + resolvedOptions.sources.forEach(s => nuxt.options.watch.push(normalize(s))) + } + } + else { + resolvedOptions.sources.forEach(s => vuetifyConfigurationFilesToWatch.add(s)) + } } // unshift since we need to use the app configuration as base in defu call (L64 below): fix #231 diff --git a/src/utils/loader.ts b/src/utils/loader.ts index e173bb4..4091368 100644 --- a/src/utils/loader.ts +++ b/src/utils/loader.ts @@ -1,9 +1,10 @@ -import { relative, resolve } from 'node:path' +import { normalize, resolve } from 'node:path' import type { Nuxt } from '@nuxt/schema' import defu from 'defu' import { debounce } from 'perfect-debounce' -import { addVitePlugin } from '@nuxt/kit' +import { addVitePlugin, isIgnored } from '@nuxt/kit' import type { ModuleNode } from 'vite' +import { watch as chokidarWatch } from 'chokidar' import type { VOptions, VuetifyModuleOptions } from '../types' import { RESOLVED_VIRTUAL_MODULES } from '../vite/constants' import { mergeVuetifyModules } from './layers' @@ -82,7 +83,7 @@ export async function load( /* handle new stuff */ ctx.moduleOptions = configuration.moduleOptions! ctx.vuetifyOptions = configuration.vuetifyOptions! - ctx.vuetifyFilesToWatch = Array.from(vuetifyConfigurationFilesToWatch) + ctx.vuetifyFilesToWatch = Array.from(vuetifyConfigurationFilesToWatch).map(f => normalize(f)) ctx.icons = prepareIcons(ctx.unocss, ctx.logger, vuetifyAppOptions) ctx.ssrClientHints = prepareSSRClientHints(nuxt.options.app.baseURL ?? '/', ctx) @@ -105,11 +106,41 @@ export function registerWatcher(options: VuetifyModuleOptions, nuxt: Nuxt, ctx: if (nuxt.options.dev) { let pageReload: (() => Promise) | undefined - nuxt.hooks.hook('builder:watch', (_event, path) => { - path = relative(nuxt.options.srcDir, resolve(nuxt.options.srcDir, path)) - if (!pageReload && ctx.vuetifyFilesToWatch.includes(path)) - return nuxt.callHook('restart') - }) + // setup watcher when using compatibilityVersion - files outside srcDir are not watched + if (nuxt.options.future?.compatibilityVersion === 4) { + const watcher = chokidarWatch( + ctx.vuetifyFilesToWatch.map(f => normalize(resolve(nuxt.options.srcDir, f))), + { + awaitWriteFinish: true, + ignoreInitial: true, + ignored: [isIgnored, 'node_modules'], + }, + ) + + watcher.on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(path))) + nuxt.hook('close', () => watcher?.close()) + nuxt.hooks.hook('builder:watch', (_event, path) => { + path = normalize(path) + if (ctx.vuetifyFilesToWatch.includes(path)) + return typeof pageReload === 'function' ? pageReload() : nuxt.callHook('restart') + }) + } + else { + nuxt.hooks.hook('builder:watch', (_event, path) => { + path = normalize(resolve(nuxt.options.srcDir, path)) + if (!pageReload && ctx.vuetifyFilesToWatch.includes(path)) + return nuxt.callHook('restart') + }) + // on v4 this is not called + addVitePlugin({ + name: 'vuetify:configuration:watch', + enforce: 'pre', + handleHotUpdate({ file }) { + if (pageReload && ctx.vuetifyFilesToWatch.includes(normalize(file))) + return pageReload() + }, + }) + } nuxt.hook('vite:serverCreated', (server, { isClient }) => { if (!server.ws || !isClient) @@ -130,14 +161,5 @@ export function registerWatcher(options: VuetifyModuleOptions, nuxt: Nuxt, ctx: await Promise.all(modules.map(m => server.reloadModule(m))) }, 50, { trailing: false }) }) - - addVitePlugin({ - name: 'vuetify:configuration:watch', - enforce: 'pre', - handleHotUpdate({ file }) { - if (pageReload && ctx.vuetifyFilesToWatch.includes(file)) - return pageReload() - }, - }) } } From 0b2f646e2bbc1aaae206d5bd546f93a60b7d1517 Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 14 Nov 2024 22:42:48 +0100 Subject: [PATCH 2/2] chore: v4 restart dev server when ssr enabled --- src/utils/loader.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/loader.ts b/src/utils/loader.ts index 4091368..c8bdb0a 100644 --- a/src/utils/loader.ts +++ b/src/utils/loader.ts @@ -117,12 +117,13 @@ export function registerWatcher(options: VuetifyModuleOptions, nuxt: Nuxt, ctx: }, ) + const ssr = nuxt.options.ssr watcher.on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(path))) nuxt.hook('close', () => watcher?.close()) nuxt.hooks.hook('builder:watch', (_event, path) => { path = normalize(path) if (ctx.vuetifyFilesToWatch.includes(path)) - return typeof pageReload === 'function' ? pageReload() : nuxt.callHook('restart') + return !ssr && typeof pageReload === 'function' ? pageReload() : nuxt.callHook('restart') }) } else {