1
0
Эх сурвалжийг харах

fix(dashboard): Enable tailwind processing of dashboard extension files

Michael Bromley 6 сар өмнө
parent
commit
694d0dd2aa

+ 3 - 0
packages/dashboard/src/app/styles.css

@@ -4,6 +4,8 @@
 
 @custom-variant dark (&:is(.dark *));
 
+/* @source rules from extensions will be added here by the dashboardTailwindSourcePlugin */
+
 /*
 * Important: This is not an actual import. We are pre-processing this CSS file
 * to inject the theme variables into the CSS. This import will be replaced
@@ -64,6 +66,7 @@
     * {
         @apply border-border outline-ring/50;
     }
+
     body {
         @apply bg-background text-foreground;
     }

+ 7 - 7
packages/dashboard/vite.config.lib.mts

@@ -1,19 +1,19 @@
-import { vendureDashboardPlugin } from './vite/vite-plugin-vendure-dashboard.js';
+import { lingui } from '@lingui/vite-plugin';
+import react from '@vitejs/plugin-react';
 import path from 'path';
 import { pathToFileURL } from 'url';
 import { defineConfig } from 'vite';
 import dts from 'vite-plugin-dts';
-import { lingui } from '@lingui/vite-plugin';
-import react from '@vitejs/plugin-react';
-import tailwindcss from '@tailwindcss/vite';
-import { configLoaderPlugin } from './vite/vite-plugin-config-loader.js';
 import { adminApiSchemaPlugin } from './vite/vite-plugin-admin-api-schema.js';
+import { configLoaderPlugin } from './vite/vite-plugin-config-loader.js';
 import { dashboardMetadataPlugin } from './vite/vite-plugin-dashboard-metadata.js';
 import { uiConfigPlugin } from './vite/vite-plugin-ui-config.js';
 import { getNormalizedVendureConfigPath } from './vite/vite-plugin-vendure-dashboard.js';
 
 const tempDir = path.join(import.meta.dirname, './.vendure-dashboard-temp');
-const normalizedVendureConfigPath = getNormalizedVendureConfigPath(pathToFileURL('./sample-vendure-config.ts'));
+const normalizedVendureConfigPath = getNormalizedVendureConfigPath(
+    pathToFileURL('./sample-vendure-config.ts'),
+);
 
 /**
  * This config file is for building the dashboard library (the shared components, hooks etc).
@@ -44,7 +44,7 @@ export default defineConfig({
         }),
         configLoaderPlugin({ vendureConfigPath: normalizedVendureConfigPath, tempDir }),
         adminApiSchemaPlugin(),
-        dashboardMetadataPlugin({ rootDir: tempDir }),
+        dashboardMetadataPlugin(),
         uiConfigPlugin({ adminUiConfig: {} }),
         dts({
             include: ['src/lib/**/*.ts', 'src/lib/**/*.tsx'],

+ 1 - 9
packages/dashboard/vite/vite-plugin-dashboard-metadata.ts

@@ -12,7 +12,7 @@ const resolvedVirtualModuleId = `\0${virtualModuleId}`;
  * generates an import statement for each one, wrapped up in a `runDashboardExtensions()`
  * function which can then be imported and executed in the Dashboard app.
  */
-export function dashboardMetadataPlugin(options: { rootDir: string }): Plugin {
+export function dashboardMetadataPlugin(): Plugin {
     let configLoaderApi: ConfigLoaderApi;
     let loadVendureConfigResult: LoadVendureConfigResult;
     return {
@@ -52,11 +52,3 @@ export function dashboardMetadataPlugin(options: { rootDir: string }): Plugin {
         },
     };
 }
-
-/**
- * Converts an import path to a normalized path relative to the rootDir.
- */
-function normalizeImportPath(rootDir: string, importPath: string): string {
-    const relativePath = path.relative(rootDir, importPath).replace(/\\/g, '/');
-    return relativePath.replace(/\.tsx?$/, '.js');
-}

+ 65 - 0
packages/dashboard/vite/vite-plugin-tailwind-source.ts

@@ -0,0 +1,65 @@
+import path from 'path';
+import { Plugin } from 'vite';
+
+import { LoadVendureConfigResult } from './utils/config-loader.js';
+import { ConfigLoaderApi, getConfigLoaderApi } from './vite-plugin-config-loader.js';
+
+/**
+ * This Vite plugin transforms the `app/styles.css` file to include a `@source` directive
+ * for each dashboard extension's source directory. This allows Tailwind CSS to
+ * include styles from these extensions when processing the CSS.
+ */
+export function dashboardTailwindSourcePlugin(): Plugin {
+    let configLoaderApi: ConfigLoaderApi;
+    let loadVendureConfigResult: LoadVendureConfigResult;
+    return {
+        name: 'vendure:dashboard-tailwind-source',
+        // Ensure this plugin runs before Tailwind CSS processing
+        enforce: 'pre',
+        configResolved({ plugins }) {
+            configLoaderApi = getConfigLoaderApi(plugins);
+        },
+        async transform(src, id) {
+            if (/app\/styles.css$/.test(id)) {
+                if (!loadVendureConfigResult) {
+                    loadVendureConfigResult = await configLoaderApi.getVendureConfig();
+                }
+                const { pluginInfo } = loadVendureConfigResult;
+                const dashboardExtensionDirs =
+                    pluginInfo
+                        ?.map(
+                            ({ dashboardEntryPath, pluginPath }) =>
+                                dashboardEntryPath && path.join(pluginPath, path.dirname(dashboardEntryPath)),
+                        )
+                        .filter(x => x != null) ?? [];
+                const sources = dashboardExtensionDirs
+                    .map(extension => {
+                        return `@source '${extension}';`;
+                    })
+                    .join('\n');
+
+                // Find the line with the specific comment and insert sources after it
+                const lines = src.split('\n');
+                const sourceCommentIndex = lines.findIndex(line =>
+                    line.includes(
+                        '/* @source rules from extensions will be added here by the dashboardTailwindSourcePlugin */',
+                    ),
+                );
+
+                if (sourceCommentIndex !== -1) {
+                    // Insert the sources after the comment line
+                    lines.splice(sourceCommentIndex + 1, 0, sources);
+                    const modifiedSrc = lines.join('\n');
+                    return {
+                        code: modifiedSrc,
+                    };
+                }
+
+                // If the comment is not found, append sources at the end
+                return {
+                    code: src + '\n' + sources,
+                };
+            }
+        },
+    };
+}

+ 5 - 3
packages/dashboard/vite/vite-plugin-vendure-dashboard.ts

@@ -10,9 +10,10 @@ import { configLoaderPlugin } from './vite-plugin-config-loader.js';
 import { viteConfigPlugin } from './vite-plugin-config.js';
 import { dashboardMetadataPlugin } from './vite-plugin-dashboard-metadata.js';
 import { gqlTadaPlugin } from './vite-plugin-gql-tada.js';
-import { ThemeVariablesPluginOptions, themeVariablesPlugin } from './vite-plugin-theme.js';
+import { dashboardTailwindSourcePlugin } from './vite-plugin-tailwind-source.js';
+import { themeVariablesPlugin, ThemeVariablesPluginOptions } from './vite-plugin-theme.js';
 import { transformIndexHtmlPlugin } from './vite-plugin-transform-index.js';
-import { UiConfigPluginOptions, uiConfigPlugin } from './vite-plugin-ui-config.js';
+import { uiConfigPlugin, UiConfigPluginOptions } from './vite-plugin-ui-config.js';
 
 /**
  * @description
@@ -121,6 +122,7 @@ export function vendureDashboardPlugin(options: VitePluginVendureDashboardOption
             // },
         }),
         themeVariablesPlugin({ theme: options.theme }),
+        dashboardTailwindSourcePlugin(),
         tailwindcss(),
         configLoaderPlugin({
             vendureConfigPath: normalizedVendureConfigPath,
@@ -130,7 +132,7 @@ export function vendureDashboardPlugin(options: VitePluginVendureDashboardOption
         }),
         viteConfigPlugin({ packageRoot }),
         adminApiSchemaPlugin(),
-        dashboardMetadataPlugin({ rootDir: tempDir }),
+        dashboardMetadataPlugin(),
         uiConfigPlugin({ adminUiConfig: options.adminUiConfig }),
         ...(options.gqlTadaOutputPath
             ? [gqlTadaPlugin({ gqlTadaOutputPath: options.gqlTadaOutputPath, tempDir, packageRoot })]