vite-plugin-dashboard-metadata.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import path from 'path';
  2. import { pathToFileURL } from 'node:url';
  3. import { Plugin } from 'vite';
  4. import { CompileResult } from './utils/compiler.js';
  5. import { ConfigLoaderApi, getConfigLoaderApi } from './vite-plugin-config-loader.js';
  6. const virtualModuleId = 'virtual:dashboard-extensions';
  7. const resolvedVirtualModuleId = `\0${virtualModuleId}`;
  8. /**
  9. * This Vite plugin scans the configured plugins for any dashboard extensions and dynamically
  10. * generates an import statement for each one, wrapped up in a `runDashboardExtensions()`
  11. * function which can then be imported and executed in the Dashboard app.
  12. */
  13. export function dashboardMetadataPlugin(): Plugin {
  14. let configLoaderApi: ConfigLoaderApi;
  15. let loadVendureConfigResult: CompileResult;
  16. return {
  17. name: 'vendure:dashboard-extensions-metadata',
  18. configResolved({ plugins }) {
  19. configLoaderApi = getConfigLoaderApi(plugins);
  20. },
  21. resolveId(id) {
  22. if (id === virtualModuleId) {
  23. return resolvedVirtualModuleId;
  24. }
  25. },
  26. async load(id) {
  27. if (id === resolvedVirtualModuleId) {
  28. const startTime = Date.now();
  29. this.debug('Loading dashboard extensions...');
  30. if (!loadVendureConfigResult) {
  31. const configStart = Date.now();
  32. loadVendureConfigResult = await configLoaderApi.getVendureConfig();
  33. this.debug(`Loaded Vendure config in ${Date.now() - configStart}ms`);
  34. }
  35. const { pluginInfo } = loadVendureConfigResult;
  36. const resolveStart = Date.now();
  37. const pluginsWithExtensions =
  38. pluginInfo
  39. ?.map(({ dashboardEntryPath, pluginPath, sourcePluginPath }) => {
  40. if (!dashboardEntryPath) {
  41. return null;
  42. }
  43. // For local plugins, use the sourcePluginPath to resolve the dashboard extension
  44. const basePath = sourcePluginPath
  45. ? path.dirname(sourcePluginPath)
  46. : path.dirname(pluginPath);
  47. const resolved = path.resolve(basePath, dashboardEntryPath);
  48. this.debug(`Resolved extension path: ${resolved}`);
  49. return resolved;
  50. })
  51. .filter(x => x != null) ?? [];
  52. this.info(
  53. `Found ${pluginsWithExtensions.length} Dashboard extensions in ${Date.now() - resolveStart}ms`,
  54. );
  55. this.debug(`Total dashboard extension loading completed in ${Date.now() - startTime}ms`);
  56. return `
  57. export async function runDashboardExtensions() {
  58. ${pluginsWithExtensions
  59. .map(extension => {
  60. return `await import(\`${pathToFileURL(extension)}\`);`;
  61. })
  62. .join('\n')}
  63. }`;
  64. }
  65. },
  66. };
  67. }