feat(vite): Ajoute la gestion des favicons via un plugin et une fonction Twig.

This commit is contained in:
Serreau Jovann
2025-10-07 16:03:42 +02:00
parent 7cd2cee6e5
commit 0c3054d7ed
5 changed files with 83 additions and 13 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -32,6 +32,7 @@
"body-scroll-lock": "^4.0.0-beta.0",
"react-email-editor": "^1.7.11",
"sortablejs": "^1.15.6",
"tailwindcss": "^4.1.13"
"tailwindcss": "^4.1.13",
"vite-plugin-favicon": "^1.0.8"
}
}

View File

@@ -8,6 +8,9 @@ use Twig\TwigFunction;
class ViteAssetExtension extends AbstractExtension
{
// Clé réservée dans le manifest Vite pour le HTML généré des favicons.
const FAVICON_MANIFEST_KEY = '_FAVICONS_HTML_';
private ?array $manifestData = null;
const CACHE_KEY = 'vite_manifest';
@@ -18,16 +21,49 @@ class ViteAssetExtension extends AbstractExtension
private readonly string $manifest,
private readonly CacheItemPoolInterface $cache,
) {
// Respecte la logique existante : VITE_LOAD == "0" est considéré comme DEV.
$this->isDev = $_ENV['VITE_LOAD'] == "0";
}
public function getFunctions(): array
{
return [
new TwigFunction('vite_asset', $this->asset(...), ['is_safe' => ['html']])
new TwigFunction('vite_asset', $this->asset(...), ['is_safe' => ['html']]),
// Nouvelle fonction Twig pour inclure les liens de favicons
new TwigFunction('vite_favicons', $this->favicons(...), ['is_safe' => ['html']])
];
}
/**
* Charge le manifeste s'il n'est pas déjà chargé et met en cache.
*/
private function loadManifest(): void
{
if ($this->manifestData === null) {
$item = $this->cache->getItem(self::CACHE_KEY);
if ($item->isHit()) {
$this->manifestData = $item->get();
} else {
if (!file_exists($this->manifest)) {
// En cas d'erreur de fichier, initialise à un tableau vide
$this->manifestData = [];
return;
}
$this->manifestData = json_decode((string)file_get_contents($this->manifest), true);
if (json_last_error() !== JSON_ERROR_NONE) {
$this->manifestData = [];
}
$item->set($this->manifestData);
$this->cache->save($item);
}
}
}
// --- Gestion des assets JS/CSS (non modifiée) ---
public function asset(string $entry, array $deps): string
{
if ($this->isDev) {
@@ -49,24 +85,16 @@ class ViteAssetExtension extends AbstractExtension
public function assetProd(string $entry): string
{
if ($this->manifestData === null) {
$item = $this->cache->getItem(self::CACHE_KEY);
if ($item->isHit()) {
$this->manifestData = $item->get();
} else {
$this->manifestData = json_decode((string)file_get_contents($this->manifest), true);
$item->set($this->manifestData);
$this->cache->save($item);
}
}
$this->loadManifest();
$file = $this->manifestData[$entry]['file'] ?? '';
$css = $this->manifestData[$entry]['css'] ?? [];
$imports = $this->manifestData[$entry]['imports'] ?? [];
$html = <<<HTML
<script type="module" src="/build/{$file}" defer></script>
HTML;
foreach ($css as $cssFile) {
$html .= <<<HTML
<link rel="stylesheet" media="screen" href="/build/{$cssFile}"/>
@@ -82,5 +110,41 @@ class ViteAssetExtension extends AbstractExtension
return $html;
}
// --- Nouvelle Gestion des Favicons ---
public function favicons(): string
{
if ($this->isDev) {
return $this->faviconsDev();
}
return $this->faviconsProd();
}
public function faviconsDev(): string
{
// En mode dev, on assume qu'un fichier favicon.ico ou favicon.png
// standard est présent dans le répertoire public.
return <<<HTML
<link rel="icon" type="image/x-icon" href="/favicon.ico">
HTML;
}
public function faviconsProd(): string
{
$this->loadManifest();
// Récupère le bloc HTML complet généré par le plugin dans le manifest.
// On suppose que l'entrée est un tableau associatif avec la clé 'html'.
$faviconData = $this->manifestData;
$faviconHtml = "";
foreach ($faviconData as $key =>$favicon) {
if(!str_contains($key,".js")) {
$faviconHtml .= <<<HTML
<link rel="icon" href="/build/{$favicon['file']}" type="image/x-icon">
HTML;
}
}
return $faviconHtml;
}
}

View File

@@ -6,6 +6,7 @@
<title>Mainframe - {% block title %}{% endblock %}</title>
<meta name="robots" content="noindex">
{{ vite_favicons() }}
{{ vite_asset('admin.js',[]) }}
<link rel="stylesheet" href="{{ asset('assets/icons/css/all.min.css') }}">

View File

@@ -5,6 +5,7 @@ import { resolve } from 'path';
import JavaScriptObfuscator from 'rollup-plugin-javascript-obfuscator';
import tailwindcss from '@tailwindcss/vite'
import preact from '@preact/preset-vite';
import ViteFaviconsPlugin from "vite-plugin-favicon";
// Si vous utilisez un framework comme Vue ou React, importez son plugin ici
// import vue from '@vitejs/plugin-vue';
@@ -84,6 +85,9 @@ export default defineConfig({
// Ajoutez ici les plugins de framework (ex: vue(), react())
tailwindcss(),
preact(),
ViteFaviconsPlugin({
logo: 'public/assets/logo.png',
}),
// --- PLUGIN D'OBSCURCISSEMENT JAVASCRIPT ---
// Doit être l'un des derniers plugins pour s'appliquer au code final.
// ATTENTION : Ces options sont très agressives et peuvent casser votre code.