Aller au contenu principal
Version: Canary đźš§

Front-End Assets

Introduction​

Bow est préconfiguré avec un environnement Frontend moderne basé sur Vite, incluant :

Cette configuration offre un rechargement instantané (HMR) et une compilation ultra-rapide.

Installation​

npm install

Commandes​

CommandeDescription
npm run devLance le serveur de développement Vite avec HMR
npm run buildCompile et optimise pour la production

Développement​

npm run dev

Lance le serveur Vite avec rechargement à chaud. Les modifications sont reflétées instantanément sans recharger la page.

Production​

npm run build

Compile et minifie les assets dans le dossier public/.

Structure des fichiers​

assets/
├── js/
│ ├── app.js # Point d'entrée principal
│ ├── Example.jsx # Composant React
│ └── Example.vue # Composant Vue
├── sass/
│ ├── app.scss # Styles principaux
│ └── variables.scss # Variables SCSS
└── css/
└── app.css # CSS/Tailwind

Configuration Vite​

vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import react from '@vitejs/plugin-react';
import path from 'path';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
plugins: [
vue(),
react(),
tailwindcss(),
],
root: path.resolve(__dirname, 'assets'),
build: {
outDir: path.resolve(__dirname, 'public'),
emptyOutDir: true,
rollupOptions: {
input: {
app: path.resolve(__dirname, 'assets/js/app.js'),
},
output: {
entryFileNames: 'js/[name].js',
assetFileNames: (assetInfo) => {
if (/\.(css|scss)$/.test(assetInfo.name)) {
return 'css/[name]-[hash][extname]';
}
if (/\.(png|jpe?g|gif|svg|webp)$/.test(assetInfo.name)) {
return 'img/[name]-[hash][extname]';
}
return '[ext]/[name]-[hash][extname]';
},
},
},
},
});

Tailwind CSS​

Configuration​

tailwind.config.js
import defaultTheme from "tailwindcss/defaultTheme";

export default {
content: [
"./templates/**/*.{blade,tintin}.php",
"./templates/**/*.twig",
"./templates/**/*.{js,jsx,ts,tsx,vue}",
"./assets/js/**/*.{js,jsx,ts,tsx,vue}",
],
theme: {
extend: {
fontFamily: {
sans: ["Figtree", ...defaultTheme.fontFamily.sans],
},
},
},
plugins: [],
};

Utilisation​

assets/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Styles personnalisés */
.btn-primary {
@apply bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600;
}

Composants React​

assets/js/Example.jsx
import React, { useState } from 'react';

export default function Example() {
const [count, setCount] = useState(0);

return (
<div className="p-4">
<h1 className="text-2xl font-bold">Compteur: {count}</h1>
<button
className="btn-primary mt-4"
onClick={() => setCount(count + 1)}
>
Incrémenter
</button>
</div>
);
}

Composants Vue​

assets/js/Example.vue
<script setup>
import { ref } from 'vue';

const count = ref(0);
</script>

<template>
<div class="p-4">
<h1 class="text-2xl font-bold">Compteur: {{ count }}</h1>
<button class="btn-primary mt-4" @click="count++">
Incrémenter
</button>
</div>
</template>

Intégration dans les templates​

Avec Tintin​

templates/app.tintin.php
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<div id="app"></div>
<script type="module" src="/js/app.js"></script>
</body>
</html>

Helper asset​

Le helper asset() construit simplement une URL vers un fichier statique du dossier public/. Il ne connaît pas le hash de cache ajouté par Vite en production — réservez-le aux fichiers dont le nom ne change pas (favicon, images statiques, etc.).

<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<script src="{{ asset('js/app.js') }}"></script>

Helper vite (assets compilés)​

En production, npm run build ajoute un hash au nom de chaque fichier (app-CBsLkjX9.js) pour le cache-busting, et enregistre la correspondance nom logique → fichier réel dans un manifeste. Le helper vite() lit ce manifeste et retourne l'URL du fichier compilé correspondant :

templates/layouts/default.tintin.php
<link rel="stylesheet" href="{{ vite('css/app.css') }}">
<script type="module" src="{{ vite('js/app.js') }}"></script>

Signature :

vite(string $file, bool $absolute = false): string
  • $file : la clĂ© d'entrĂ©e dans le manifeste (ex. js/app.js). Chaque fichier rĂ©fĂ©rencĂ© doit ĂŞtre dĂ©clarĂ© comme entrĂ©e (input) dans vite.config.js pour apparaĂ®tre dans le manifeste.
  • $absolute : si true, l'URL est prĂ©fixĂ©e par l'URL de l'application (via url()) au lieu d'ĂŞtre relative.
  • Lève une Exception si l'entrĂ©e n'existe pas dans le manifeste.

Le helper cherche le manifeste, dans l'ordre, aux emplacements suivants :

public/build/.vite/manifest.json
public/build/manifest.json
public/.vite/manifest.json
manifest.json (racine du projet)
Chemin servi

vite() renvoie des URLs préfixées par /build/ (ex. /build/js/app-CBsLkjX9.js). Les fichiers compilés doivent donc être servis sous /build/ : assurez-vous que la sortie du build (outDir dans vite.config.js) et l'emplacement du manifeste sont cohérents avec ce préfixe.

Développement vs production

Pendant npm run dev, les assets sont servis par le serveur Vite avec HMR. Le helper vite() n'est utile qu'après un npm run build, quand le manifeste existe. Pensez à lancer le build avant de tester en mode production.

Variables d'environnement​

Vite expose les variables préfixées par VITE_ :

.env.json
{
"VITE_APP_NAME": "Mon App",
"VITE_API_URL": "https://api.example.com"
}
// Accès dans le code
const appName = import.meta.env.VITE_APP_NAME;
Documentation

Pour plus d'informations, consultez la documentation Vite.

Il manque quelque chose ?

Si vous rencontrez des problèmes avec la documentation ou si vous avez des suggestions pour améliorer la documentation ou le projet en général, veuillez déposer une issue pour nous, ou envoyer un tweet mentionnant le compte Twitter @bowframework ou sur directement sur le github.