vite-plugin-vendure-dashboard.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import tailwindcss from '@tailwindcss/vite';
  2. import { TanStackRouterVite } from '@tanstack/router-plugin/vite';
  3. import react from '@vitejs/plugin-react';
  4. import path from 'path';
  5. import { PluginOption } from 'vite';
  6. import { adminApiSchemaPlugin } from './vite-plugin-admin-api-schema.js';
  7. import { configLoaderPlugin } from './vite-plugin-config-loader.js';
  8. import { viteConfigPlugin } from './vite-plugin-config.js';
  9. import { dashboardMetadataPlugin } from './vite-plugin-dashboard-metadata.js';
  10. import { gqlTadaPlugin } from './vite-plugin-gql-tada.js';
  11. import { ThemeVariablesPluginOptions, themeVariablesPlugin } from './vite-plugin-theme.js';
  12. import { UiConfigPluginOptions, uiConfigPlugin } from './vite-plugin-ui-config.js';
  13. /**
  14. * @description
  15. * Options for the {@link vendureDashboardPlugin} Vite plugin.
  16. */
  17. export type VitePluginVendureDashboardOptions = {
  18. /**
  19. * @description
  20. * The path to the Vendure server configuration file.
  21. */
  22. vendureConfigPath: string | URL;
  23. /**
  24. * @description
  25. * The name of the exported variable from the Vendure server configuration file.
  26. * This is only required if the plugin is unable to auto-detect the name of the exported variable.
  27. */
  28. vendureConfigExport?: string;
  29. /**
  30. * @description
  31. * The path to the directory where the generated GraphQL Tada files will be output.
  32. */
  33. gqlTadaOutputPath?: string;
  34. tempCompilationDir?: string;
  35. disableTansStackRouterPlugin?: boolean;
  36. /**
  37. * @description
  38. * If set to `true`, compilation errors during the build process will be reported and
  39. * the build will fail.
  40. *
  41. * @default false
  42. */
  43. reportCompilationErrors?: boolean;
  44. } & UiConfigPluginOptions &
  45. ThemeVariablesPluginOptions;
  46. /**
  47. * @description
  48. * This is a Vite plugin which configures a set of plugins required to build the Vendure Dashboard.
  49. */
  50. export function vendureDashboardPlugin(options: VitePluginVendureDashboardOptions): PluginOption[] {
  51. const tempDir = options.tempCompilationDir ?? path.join(import.meta.dirname, './.vendure-dashboard-temp');
  52. const normalizedVendureConfigPath = getNormalizedVendureConfigPath(options.vendureConfigPath);
  53. const packageRoot = getDashboardPackageRoot();
  54. const linguiConfigPath = path.join(packageRoot, 'lingui.config.js');
  55. if (process.env.IS_LOCAL_DEV !== 'true') {
  56. process.env.LINGUI_CONFIG = linguiConfigPath;
  57. }
  58. return [
  59. // TODO: solve https://github.com/kentcdodds/babel-plugin-macros/issues/87
  60. // lingui(),
  61. ...(options.disableTansStackRouterPlugin
  62. ? []
  63. : [
  64. TanStackRouterVite({
  65. autoCodeSplitting: true,
  66. routeFileIgnorePattern: '.graphql.ts|components',
  67. routesDirectory: path.join(packageRoot, 'src/app/routes'),
  68. generatedRouteTree: path.join(packageRoot, 'src/app/routeTree.gen.ts'),
  69. }),
  70. ]),
  71. react({
  72. // babel: {
  73. // plugins: ['@lingui/babel-plugin-lingui-macro'],
  74. // },
  75. }),
  76. themeVariablesPlugin({ theme: options.theme }),
  77. tailwindcss(),
  78. configLoaderPlugin({
  79. vendureConfigPath: normalizedVendureConfigPath,
  80. tempDir,
  81. reportCompilationErrors: options.reportCompilationErrors,
  82. }),
  83. viteConfigPlugin({ packageRoot }),
  84. adminApiSchemaPlugin(),
  85. dashboardMetadataPlugin({ rootDir: tempDir }),
  86. uiConfigPlugin({ adminUiConfig: options.adminUiConfig }),
  87. ...(options.gqlTadaOutputPath
  88. ? [gqlTadaPlugin({ gqlTadaOutputPath: options.gqlTadaOutputPath, tempDir, packageRoot })]
  89. : []),
  90. ];
  91. }
  92. /**
  93. * @description
  94. * Returns the path to the root of the `@vendure/dashboard` package.
  95. */
  96. function getDashboardPackageRoot(): string {
  97. const fileUrl = import.meta.resolve('@vendure/dashboard');
  98. const packagePath = fileUrl.startsWith('file:') ? new URL(fileUrl).pathname : fileUrl;
  99. return fixWindowsPath(path.join(packagePath, '../../../'));
  100. }
  101. /**
  102. * Get the normalized path to the Vendure config file given either a string or URL.
  103. */
  104. export function getNormalizedVendureConfigPath(vendureConfigPath: string | URL): string {
  105. const stringPath = typeof vendureConfigPath === 'string' ? vendureConfigPath : vendureConfigPath.href;
  106. if (stringPath.startsWith('file:')) {
  107. return fixWindowsPath(new URL(stringPath).pathname);
  108. }
  109. return fixWindowsPath(stringPath);
  110. }
  111. function fixWindowsPath(filePath: string): string {
  112. // Fix Windows paths that might start with a leading slash
  113. if (process.platform === 'win32') {
  114. // Remove leading slash before drive letter on Windows
  115. if (/^[/\\][A-Za-z]:/.test(filePath)) {
  116. return filePath.substring(1);
  117. }
  118. }
  119. return filePath;
  120. }