import basicSsl from "@vitejs/plugin-basic-ssl"; import vue from "@vitejs/plugin-vue"; import autoprefixer from "autoprefixer"; import laravel from "laravel-vite-plugin"; import path from "node:path"; import postcssDiscard from "postcss-discard-comments"; import { defineConfig, loadEnv } from "vite"; import checker from "vite-plugin-checker"; import eslint from "vite-plugin-eslint2"; import { viteStaticCopy } from "vite-plugin-static-copy"; const env = loadEnv("r", process.cwd(), ""); const isCI = !!process.env.CI; const debugMode = ["local", "development"].includes(process.env.NODE_ENV ?? ""); const browserTargets = ["es2019", "edge92", "firefox88", "chrome92", "safari15"]; export default defineConfig({ build: { chunkSizeWarningLimit: 1500, target: browserTargets, cssTarget: browserTargets, emptyOutDir: true, sourcemap: debugMode ? "inline" : false, rollupOptions: { output: { entryFileNames: `assets/${debugMode ? "[name]-" : ""}[hash].js`, chunkFileNames: `assets/${debugMode ? "[name]-" : ""}[hash].js`, manualChunks(id) { if (id.includes("node_modules")) { // ! Isole Bootstrap if (id.includes("bootstrap")) return "vendor-bootstrap"; // ! Isole Vue if (id.includes("vue")) return "vendor-vue"; // ! Isole FontAwesome if (id.includes("@fortawesome")) return "vendor-fontawesome"; // ! Isole Ckeditor if (id.includes("ckeditor")) return "vendor-ckeditor"; return "vendor"; } }, assetFileNames: (chunk) => { if ( Array.isArray(chunk.names) && (chunk.names.some(name => String(name).endsWith("mail-theme.scss")) || chunk.names.includes("mail-theme.css")) ) { return "vendor/mail/html/themes/default.[ext]"; } return `assets/${debugMode ? "[name]-" : ""}[hash].[ext]`; }, }, }, }, css: { devSourcemap: debugMode, preprocessorOptions: { scss: { silenceDeprecations: ["color-functions", "global-builtin", "import", "if-function"] }, }, postcss: { map: { inline: true }, plugins: [ { // Hack pour dégager les code css invalid de cookie notice postcssPlugin: "remove-empty-var", Declaration(decl) { if (decl?.value.includes("var()")) { decl.remove(); } } }, postcssDiscard({ removeAll: true }), autoprefixer(), ], }, }, plugins: [ { name: "hmr-symlink-fix", configureServer(server) { // * Forcer la détection uniquement sur le thème actif dans mounted et sur le moteur server.watcher.add(path.resolve(process.cwd(), "resources/theme/mounted")); server.watcher.add(path.resolve(process.cwd(), "resources/sass")); }, handleHotUpdate({ file, server }) { if (file.endsWith(".scss")) { const modulesToUpdate = []; for (const mod of server.moduleGraph.idToModuleMap.values()) { if (!mod.file) continue; const isFo = mod.file.endsWith("sass/fo.scss"); const isMail = mod.file.endsWith("sass/mail-theme.scss"); const isBo = mod.file.endsWith("sass/bo.scss"); if (isFo || isMail || isBo) { if (file.includes("/resources/theme/mounted/") && (isFo || isMail)) { server.moduleGraph.invalidateModule(mod); modulesToUpdate.push(mod); } else if (file.includes("/resources/sass/") && isBo) { server.moduleGraph.invalidateModule(mod); modulesToUpdate.push(mod); } } } if (modulesToUpdate.length > 0) { for (const mod of modulesToUpdate) { server.ws.send({ type: "update", updates: [ { type: "css-update", path: mod.url, acceptedPath: mod.url, timestamp: Date.now() } ] }); } return modulesToUpdate; } } } }, basicSsl(), ...(isCI ? [] : [ checker({ vueTsc: { root: ".", tsconfigPath: "tsconfig.json" }, typescript: { root: ".", tsconfigPath: "tsconfig.json" }, stylelint: { lintCommand: "stylelint --quiet -c .stylelintrc.json --fix 'resources/sass/**/*.scss' 'resources/theme/mounted/**/*.scss'", }, }) ]), laravel({ input: [ "resources/sass/bo.scss", "resources/ts/bo.ts", "resources/theme/mounted/sass/mail-theme.scss", "resources/theme/mounted/sass/fo.scss", "resources/theme/mounted/ts/fo.ts", "resources/sass/vendor/ckEditorContent.scss", ], refresh: [ "resources/views/**/*.blade.php", "resources/theme/mounted/views/**/*.blade.php", ], }), viteStaticCopy({ targets: [ { src: "resources/theme/mounted/favicon/*", dest: "../", rename: { stripBase: true }, }, { src: "resources/favicon/*", dest: "../", rename: { stripBase: true }, overwrite: false, }, ], }), eslint({ cache: false, include: ["resources/ts/**/*.ts", "resources/theme/mounted/ts/**/*.ts"], exclude: ["node_modules", "vendor"], lintOnStart: false, emitWarning: true, emitError: true, }), vue({ isProduction: !debugMode, exclude: ["node_modules", "vendor"], }) ], server: { host: env["APP_URL"] ? new URL(env["APP_URL"]).hostname : "", port: 4443, watch: { usePolling: true, followSymlinks: true, ignored: ["!**/resources/theme/mounted/**"] }, }, resolve: { preserveSymlinks: true, extensions: ["*", ".js", ".ts", ".vue"], alias: [ { find: "vue", replacement: "vue/dist/vue.runtime.esm-bundler.js", }, { find: "@", replacement: "/resources/assets", }, { find: "@Theme", replacement: "/resources/theme/mounted/assets", }, { find: "~", replacement: path.resolve(process.cwd(), "./node_modules"), }, ], }, });