From cb9b6f91d92ffbda8906c575dcb85bf4f9c53103 Mon Sep 17 00:00:00 2001
From: Stanislav Lashmanov <slashmanov@gitlab.com>
Date: Thu, 15 Aug 2024 11:33:49 +0400
Subject: [PATCH] Fix image references when using Vite

---
 config/helpers/vite_plugin_images.mjs | 56 +++++++++++++++++++++++++++
 vite.config.js                        |  2 +
 2 files changed, 58 insertions(+)
 create mode 100644 config/helpers/vite_plugin_images.mjs

diff --git a/config/helpers/vite_plugin_images.mjs b/config/helpers/vite_plugin_images.mjs
new file mode 100644
index 000000000000..993612c6e89a
--- /dev/null
+++ b/config/helpers/vite_plugin_images.mjs
@@ -0,0 +1,56 @@
+import path from 'node:path';
+import { readdir } from 'node:fs/promises';
+
+const imagesPaths = [
+  path.resolve(__dirname, '../..', 'app/assets/images'),
+  path.resolve(__dirname, '../..', 'ee/app/assets/images'),
+  path.resolve(__dirname, '../..', 'jh/app/assets/images'),
+];
+
+async function getAllFiles(dir, prependPath = '') {
+  const result = [];
+  let files = []
+  try {
+    files = await readdir(dir, { withFileTypes: true });
+  } catch(e) {}
+
+  for (const file of files) {
+    const filePath = path.join(dir, file.name);
+
+    if (file.isDirectory()) {
+      const nestedFiles = await getAllFiles(filePath, `${prependPath}${file.name}/`);
+      result.push(...nestedFiles);
+    } else {
+      result.push(prependPath + file.name);
+    }
+  }
+
+  return result;
+}
+
+export async function ImagesPlugin() {
+  return {
+    name: 'vite-plugin-gitlab-images',
+    async config() {
+      const [CEfiles, EEfiles, JHfiles] = await Promise.all(imagesPaths.map(async imagesPath => await getAllFiles(imagesPath)));
+      const [CEpath, EEpath, JHpath] = imagesPaths;
+      const mappings = [[CEpath, CEfiles], [EEpath, EEfiles], [JHpath, JHfiles]].reduce((acc, [filesPath, filenames]) => {
+        filenames.forEach(filename => {
+          acc[filename] = path.resolve(filesPath, filename);
+        });
+        return acc;
+      }, {});
+      const alias = Object.keys(mappings).map(mapping => {
+        return {
+          find: mapping,
+          replacement: mappings[mapping],
+        }
+      });
+      return {
+        resolve: {
+          alias,
+        },
+      };
+    },
+  };
+}
diff --git a/vite.config.js b/vite.config.js
index 73d1d6e7038d..010478b55847 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -21,6 +21,7 @@ import { PageEntrypointsPlugin } from './config/helpers/vite_plugin_page_entrypo
 import { FixedRubyPlugin } from './config/helpers/vite_plugin_ruby_fixed.mjs';
 import { StylePlugin } from './config/helpers/vite_plugin_style.mjs';
 import { IconsPlugin } from './config/helpers/vite_plugin_icons.mjs';
+import { ImagesPlugin } from './config/helpers/vite_plugin_images.mjs';
 /* eslint-enable import/extensions */
 
 let viteGDKConfig;
@@ -86,6 +87,7 @@ export default defineConfig({
   plugins: [
     PageEntrypointsPlugin(),
     IconsPlugin(),
+    ImagesPlugin(),
     StylePlugin({ shouldWatch: viteGDKConfig.hmr !== null }),
     viteTailwindCompilerPlugin({ shouldWatch: viteGDKConfig.hmr !== null }),
     CopyPlugin({
-- 
GitLab