vite-plugin-config-loader.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { Plugin } from 'vite';
  2. import { ConfigLoaderOptions, loadVendureConfig, LoadVendureConfigResult } from './utils/config-loader.js';
  3. export interface ConfigLoaderApi {
  4. getVendureConfig(): Promise<LoadVendureConfigResult>;
  5. }
  6. export const configLoaderName = 'vendure:config-loader';
  7. /**
  8. * This Vite plugin loads the VendureConfig from the specified file path, and
  9. * makes it available to other plugins via the `ConfigLoaderApi`.
  10. */
  11. export function configLoaderPlugin(options: ConfigLoaderOptions): Plugin {
  12. let result: LoadVendureConfigResult;
  13. const onConfigLoaded: Array<() => void> = [];
  14. return {
  15. name: configLoaderName,
  16. async buildStart() {
  17. this.info(
  18. `Loading Vendure config. This can take a short while depending on the size of your project...`,
  19. );
  20. try {
  21. const startTime = Date.now();
  22. result = await loadVendureConfig({
  23. tempDir: options.tempDir,
  24. vendureConfigPath: options.vendureConfigPath,
  25. vendureConfigExport: options.vendureConfigExport,
  26. logger: {
  27. info: (message: string) => this.info(message),
  28. warn: (message: string) => this.warn(message),
  29. debug: (message: string) => this.debug(message),
  30. },
  31. });
  32. const endTime = Date.now();
  33. const duration = endTime - startTime;
  34. const pluginNames = result.pluginInfo.map(p => p.name).join(', ');
  35. this.info(`Found ${result.pluginInfo.length} plugins: ${pluginNames}`);
  36. this.info(
  37. `Vendure config loaded (using export "${result.exportedSymbolName}") in ${duration}ms`,
  38. );
  39. } catch (e: unknown) {
  40. if (e instanceof Error) {
  41. this.error(`Error loading Vendure config: ${e.message}`);
  42. }
  43. }
  44. onConfigLoaded.forEach(fn => fn());
  45. },
  46. api: {
  47. getVendureConfig(): Promise<LoadVendureConfigResult> {
  48. if (result) {
  49. return Promise.resolve(result);
  50. } else {
  51. return new Promise<LoadVendureConfigResult>(resolve => {
  52. onConfigLoaded.push(() => {
  53. resolve(result);
  54. });
  55. });
  56. }
  57. },
  58. } satisfies ConfigLoaderApi,
  59. };
  60. }
  61. /**
  62. * Inter-plugin dependencies implemented following the pattern given here:
  63. * https://rollupjs.org/plugin-development/#direct-plugin-communication
  64. */
  65. export function getConfigLoaderApi(plugins: readonly Plugin[]): ConfigLoaderApi {
  66. const parentPlugin = plugins.find(plugin => plugin.name === configLoaderName);
  67. if (!parentPlugin) {
  68. throw new Error(`This plugin depends on the "${configLoaderName}" plugin.`);
  69. }
  70. return parentPlugin.api as ConfigLoaderApi;
  71. }