✨ feat(vite): Ajoute la gestion des favicons via un plugin et une fonction Twig.
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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') }}">
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user