vite-plugin-dashboard-metadata.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { VendureConfig } from '@vendure/core';
  2. import { getPluginDashboardExtensions } from '@vendure/core';
  3. import path from 'path';
  4. import { Plugin } from 'vite';
  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(options: { rootDir: string }): Plugin {
  14. let configLoaderApi: ConfigLoaderApi;
  15. let vendureConfig: VendureConfig;
  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. if (!vendureConfig) {
  29. vendureConfig = await configLoaderApi.getVendureConfig();
  30. }
  31. const extensions = getPluginDashboardExtensions(vendureConfig.plugins ?? []);
  32. const extensionData: Array<{ importPath: string }> = extensions.map(extension => {
  33. const providedPath = typeof extension === 'string' ? extension : extension.location;
  34. const jsPath = normalizeImportPath(options.rootDir, providedPath);
  35. return { importPath: `./${jsPath}` };
  36. });
  37. this.info(`Found ${extensionData.length} Dashboard extensions`);
  38. return `
  39. export async function runDashboardExtensions() {
  40. ${extensionData.map(extension => `await import('${extension.importPath}');`).join('\n')}
  41. }
  42. `;
  43. }
  44. },
  45. };
  46. }
  47. /**
  48. * Converts an import path to a normalized path relative to the rootDir.
  49. */
  50. function normalizeImportPath(rootDir: string, importPath: string): string {
  51. const relativePath = path.relative(rootDir, importPath).replace(/\\/g, '/');
  52. return relativePath.replace(/\.tsx?$/, '.js');
  53. }