Просмотр исходного кода

fix(dashboard): Implement partial HMR for dashboard extensions

Michael Bromley 3 месяцев назад
Родитель
Сommit
930af00edb

+ 42 - 0
packages/dashboard/vite/vite-plugin-hmr.ts

@@ -0,0 +1,42 @@
+import { ModuleNode, Plugin } from 'vite';
+
+/**
+ * @description
+ * This plugin enables kind-of HMR for when dashboard extension files change.
+ * It is not true HMR because it triggers a page reload. Making real HMR work is very
+ * tricky in this case due to the way we load extension files via virtual modules.
+ */
+export function hmrPlugin(): Plugin {
+    let viteRoot: string;
+
+    return {
+        name: 'vendure:hmr',
+        configResolved(config) {
+            viteRoot = config.root;
+        },
+        handleHotUpdate({ server, modules, timestamp, file }) {
+            const invalidatedModules = new Set<ModuleNode>();
+
+            for (const mod of modules) {
+                server.moduleGraph.invalidateModule(mod, invalidatedModules, timestamp, true);
+
+                // Check if this is a file outside the Vite root (e.g., dashboard extensions)
+                const isOutsideRoot = mod.file && !mod.file.startsWith(viteRoot);
+
+                if (isOutsideRoot) {
+                    // For files outside root, trigger a full page reload
+                    // This ensures all extension code is fresh
+                    server.ws.send({
+                        type: 'full-reload',
+                        path: '*',
+                    });
+
+                    return [];
+                }
+            }
+
+            // Let Vite handle normal HMR for files inside root
+            return undefined;
+        },
+    };
+}

+ 2 - 0
packages/dashboard/vite/vite-plugin-vendure-dashboard.ts

@@ -12,6 +12,7 @@ import { configLoaderPlugin } from './vite-plugin-config-loader.js';
 import { viteConfigPlugin } from './vite-plugin-config.js';
 import { dashboardMetadataPlugin } from './vite-plugin-dashboard-metadata.js';
 import { gqlTadaPlugin } from './vite-plugin-gql-tada.js';
+import { hmrPlugin } from './vite-plugin-hmr.js';
 import { dashboardTailwindSourcePlugin } from './vite-plugin-tailwind-source.js';
 import { themeVariablesPlugin, ThemeVariablesPluginOptions } from './vite-plugin-theme.js';
 import { transformIndexHtmlPlugin } from './vite-plugin-transform-index.js';
@@ -140,6 +141,7 @@ export function vendureDashboardPlugin(options: VitePluginVendureDashboardOption
         translationsPlugin({
             packageRoot,
         }),
+        hmrPlugin(),
     ];
 }