vite-plugin-config-loader.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { VendureConfig } from '@vendure/core';
  2. import { Plugin } from 'vite';
  3. import { ConfigLoaderOptions, loadVendureConfig } from './config-loader.js';
  4. export interface ConfigLoaderApi {
  5. getVendureConfig(): Promise<VendureConfig>;
  6. }
  7. export const configLoaderName = 'vendure:config-loader';
  8. /**
  9. * This Vite plugin loads the VendureConfig from the specified file path, and
  10. * makes it available to other plugins via the `ConfigLoaderApi`.
  11. */
  12. export function configLoaderPlugin(options: ConfigLoaderOptions): Plugin {
  13. let vendureConfig: VendureConfig;
  14. const onConfigLoaded: Array<() => void> = [];
  15. return {
  16. name: configLoaderName,
  17. async buildStart() {
  18. this.info(
  19. `Loading Vendure config. This can take a short while depending on the size of your project...`,
  20. );
  21. try {
  22. const startTime = Date.now();
  23. const result = await loadVendureConfig({
  24. tempDir: options.tempDir,
  25. vendureConfigPath: options.vendureConfigPath,
  26. vendureConfigExport: options.vendureConfigExport,
  27. logger: {
  28. info: (message: string) => this.info(message),
  29. warn: (message: string) => this.warn(message),
  30. debug: (message: string) => this.debug(message),
  31. },
  32. });
  33. vendureConfig = result.vendureConfig;
  34. const endTime = Date.now();
  35. const duration = endTime - startTime;
  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<VendureConfig> {
  48. if (vendureConfig) {
  49. return Promise.resolve(vendureConfig);
  50. } else {
  51. return new Promise<VendureConfig>(resolve => {
  52. onConfigLoaded.push(() => {
  53. resolve(vendureConfig);
  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. }