Guide Complet TechStack
Documentation complète pour maîtriser TechStack de A à Z
Bienvenue dans la documentation officielle de TechStack. Ce guide vous accompagnera dans l'apprentissage et la maîtrise de tous les aspects du framework, des concepts de base aux techniques avancées.
📘 À propos de cette documentation
Cette documentation est organisée de manière progressive. Nous vous recommandons de suivre l'ordre des chapitres si vous débutez avec TechStack.
Installation
TechStack peut être installé de plusieurs façons selon vos besoins et votre environnement de développement.
Installation via NPM
La méthode la plus simple consiste à utiliser npm ou yarn :
npm install techstack
# Ou avec Yarn
yarn add techstack
# Ou avec pnpm
pnpm add techstack
Installation via CDN
Pour un prototype rapide ou une utilisation simple, vous pouvez utiliser un CDN :
<script src="https://cdn.techstack.io/v2.0.0/techstack.min.js"></script>
<script>
const app = TechStack.createApp();
</script>
⚠️ Note importante
L'utilisation du CDN n'est pas recommandée pour la production. Préférez l'installation via npm pour bénéficier du tree-shaking et des optimisations.
Démarrage rapide
Créez votre première application TechStack en quelques minutes.
Votre première application
Créez un fichier app.js et ajoutez le code suivant :
import { TechStack } from 'techstack';
// Créer une instance de l'application
const app = new TechStack({
target: '#app',
mode: 'development'
});
// Définir un composant simple
app.component('HelloWorld', {
template: `
<div class="greeting">
<h1>{{ message }}</h1>
<button @click="updateMessage">
Changer le message
</button>
</div>
`,
data() {
return {
message: 'Bienvenue dans TechStack!'
};
},
methods: {
updateMessage() {
this.message = 'Message mis à jour!';
}
}
});
// Monter l'application
app.mount();
Structure HTML
Créez un fichier index.html :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TechStack App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./app.js"></script>
</body>
</html>
✅ Félicitations!
Vous avez créé votre première application TechStack. Ouvrez le fichier HTML dans votre navigateur pour voir le résultat.
Architecture
TechStack suit une architecture modulaire et component-based qui facilite la création d'applications scalables et maintenables.
Vue d'ensemble
L'architecture de TechStack repose sur trois piliers fondamentaux :
- Composants réactifs - Système de réactivité basé sur les proxies
- Routage déclaratif - Navigation intuitive et type-safe
- Gestion d'état centralisée - Store global avec actions et mutations
Cycle de vie des composants
Chaque composant TechStack passe par plusieurs phases durant son existence :
app.component('LifecycleDemo', {
// 1. Initialisation
beforeCreate() {
console.log('Avant la création du composant');
},
// 2. Création
created() {
console.log('Composant créé, données disponibles');
},
// 3. Montage
beforeMount() {
console.log('Avant le montage dans le DOM');
},
mounted() {
console.log('Composant monté dans le DOM');
// Accès au DOM possible ici
},
// 4. Mise à jour
beforeUpdate() {
console.log('Avant la mise à jour du composant');
},
updated() {
console.log('Composant mis à jour');
},
// 5. Démontage
beforeUnmount() {
console.log('Avant le démontage du composant');
},
unmounted() {
console.log('Composant démonté, nettoyage effectué');
}
});
Composants
Les composants sont les blocs de construction fondamentaux d'une application TechStack.
Composants de base
Un composant simple se définit avec un template, des données et des méthodes :
app.component('Counter', {
template: `
<div class="counter">
<p>Compteur: {{ count }}</p>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="reset">Reset</button>
</div>
`,
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
},
decrement() {
this.count--;
},
reset() {
this.count = 0;
}
}
});
Props et communication
Les composants peuvent recevoir des données via des props :
app.component('UserCard', {
props: {
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
role: {
type: String,
default: 'user'
}
},
template: `
<div class="user-card">
<h3>{{ username }}</h3>
<p>{{ email }}</p>
<span class="badge">{{ role }}</span>
</div>
`
});
Événements personnalisés
Les composants enfants peuvent communiquer avec leurs parents via des événements :
// Composant enfant
app.component('ChildComponent', {
methods: {
handleClick() {
this.$emit('custom-event', { data: 'valeur' });
}
}
});
// Composant parent
app.component('ParentComponent', {
template: `
<ChildComponent @custom-event="handleCustomEvent" />
`,
methods: {
handleCustomEvent(payload) {
console.log('Événement reçu:', payload);
}
}
});
Routage
Le système de routage de TechStack permet de créer des applications single-page avec navigation fluide.
Configuration du routeur
import { createRouter } from 'techstack/router';
const router = createRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: HomePage
},
{
path: '/about',
name: 'about',
component: AboutPage
},
{
path: '/users/:id',
name: 'user',
component: UserPage,
props: true
},
{
path: '/admin',
component: AdminLayout,
children: [
{
path: 'dashboard',
component: AdminDashboard
},
{
path: 'users',
component: AdminUsers
}
]
}
]
});
app.use(router);
Navigation programmatique
// Navigation simple
router.push('/about');
// Navigation avec paramètres
router.push({
name: 'user',
params: { id: 123 }
});
// Navigation avec query
router.push({
path: '/search',
query: { q: 'techstack' }
});
// Retour en arrière
router.back();
// Remplacer l'entrée courante
router.replace('/new-page');
Gestion d'état
TechStack inclut un système de gestion d'état centralisé inspiré de Vuex et Redux.
Configuration du store
import { createStore } from 'techstack/store';
const store = createStore({
state: {
user: null,
isAuthenticated: false,
cart: []
},
getters: {
cartTotal(state) {
return state.cart.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
},
cartItemCount(state) {
return state.cart.length;
}
},
mutations: {
SET_USER(state, user) {
state.user = user;
state.isAuthenticated = true;
},
LOGOUT(state) {
state.user = null;
state.isAuthenticated = false;
},
ADD_TO_CART(state, product) {
const existing = state.cart.find(
item => item.id === product.id
);
if (existing) {
existing.quantity++;
} else {
state.cart.push({ ...product, quantity: 1 });
}
}
},
actions: {
async login({ commit }, credentials) {
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify(credentials)
});
const user = await response.json();
commit('SET_USER', user);
},
logout({ commit }) {
commit('LOGOUT');
}
}
});
app.use(store);
Utilisation dans les composants
app.component('CartSummary', {
computed: {
total() {
return this.$store.getters.cartTotal;
},
itemCount() {
return this.$store.getters.cartItemCount;
}
},
methods: {
addProduct(product) {
this.$store.commit('ADD_TO_CART', product);
}
}
});
TechStack offre plusieurs stratégies pour optimiser les performances de vos applications.
Lazy Loading
Chargez vos composants à la demande pour réduire le bundle initial :
const routes = [
{
path: '/dashboard',
component: () => import('./views/Dashboard.vue')
},
{
path: '/profile',
component: () => import('./views/Profile.vue')
}
];
Mémoïsation
Utilisez la mémoïsation pour éviter les calculs coûteux :
import { computed, memo } from 'techstack';
app.component('ExpensiveComponent', {
setup() {
const expensiveResult = computed(() => {
return heavyCalculation(data.value);
});
return { expensiveResult };
}
});
Tests
TechStack facilite l'écriture de tests unitaires et d'intégration.
Tests unitaires
import { mount } from '@techstack/test-utils';
import Counter from './Counter.vue';
describe('Counter Component', () => {
it('renders initial count', () => {
const wrapper = mount(Counter);
expect(wrapper.text()).toContain('Compteur: 0');
});
it('increments count when button clicked', async () => {
const wrapper = mount(Counter);
await wrapper.find('button').trigger('click');
expect(wrapper.vm.count).toBe(1);
});
it('decrements count correctly', async () => {
const wrapper = mount(Counter, {
data() {
return { count: 5 };
}
});
await wrapper.findAll('button')[1].trigger('click');
expect(wrapper.vm.count).toBe(4);
});
});
Tests d'intégration
import { createTestApp } from '@techstack/test-utils';
import App from './App.vue';
describe('Application Flow', () => {
let app;
beforeEach(() => {
app = createTestApp(App);
});
it('navigates to user page', async () => {
await app.router.push('/users/123');
expect(app.router.currentRoute.value.name).toBe('user');
expect(app.router.currentRoute.value.params.id).toBe('123');
});
it('updates store on login', async () => {
await app.store.dispatch('login', {
email: 'test@example.com',
password: 'password'
});
expect(app.store.state.isAuthenticated).toBe(true);
});
});
Déploiement
Guide pour déployer votre application TechStack en production.
Build de production
Créez un build optimisé pour la production :
# Build avec optimisations
npm run build
# Build avec analyse du bundle
npm run build -- --analyze
# Build avec rapport de couverture
npm run build -- --report
💡 Optimisations automatiques
Le build de production inclut automatiquement : minification, tree-shaking, code splitting, compression gzip, et optimisation des assets.
Variables d'environnement
Gérez vos variables d'environnement avec des fichiers .env :
# .env.production
VITE_API_URL=https://api.production.com
VITE_APP_KEY=prod_key_here
VITE_ENABLE_ANALYTICS=true
// Utilisation dans le code
const apiUrl = import.meta.env.VITE_API_URL;
const appKey = import.meta.env.VITE_APP_KEY;
Vercel
# Installation de Vercel CLI
npm i -g vercel
# Déploiement
vercel --prod
Netlify
# Installation de Netlify CLI
npm i -g netlify-cli
# Déploiement
netlify deploy --prod --dir=dist
Docker
Créez un Dockerfile pour containeriser votre application :
# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Sécurité
Les meilleures pratiques de sécurité pour vos applications TechStack.
Protection XSS
TechStack échappe automatiquement le contenu HTML, mais restez vigilant :
// ❌ DANGEREUX - N'utilisez jamais v-html avec du contenu utilisateur
<div v-html="userInput"></div>
// ✅ BON - Utilisez l'interpolation standard
<div>{{ userInput }}</div>
// ✅ BON - Si vous devez utiliser v-html, sanitizez d'abord
import DOMPurify from 'dompurify';
<div v-html="DOMPurify.sanitize(userInput)"></div>
Protection CSRF
Implémentez des tokens CSRF pour protéger vos formulaires :
// Configuration axios avec token CSRF
import axios from 'axios';
const api = axios.create({
baseURL: '/api',
headers: {
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
}
});
// Intercepteur pour rafraîchir le token
api.interceptors.request.use(config => {
const token = document.querySelector('meta[name="csrf-token"]').content;
config.headers['X-CSRF-Token'] = token;
return config;
});
Authentification sécurisée
Stockez les tokens de manière sécurisée :
// ❌ MAUVAIS - Ne stockez pas de tokens sensibles dans localStorage
localStorage.setItem('token', authToken);
// ✅ BON - Utilisez httpOnly cookies
// Configuré côté serveur :
Set-Cookie: token=xxx; HttpOnly; Secure; SameSite=Strict
// Ou utilisez un store en mémoire avec refresh token
const tokenStore = {
accessToken: null,
refreshToken: null // Stocké dans httpOnly cookie
};
🔒 Sécurité des données
Ne stockez jamais de données sensibles (mots de passe, tokens, informations personnelles) en clair dans le localStorage ou sessionStorage. Utilisez des cookies httpOnly ou un store en mémoire.
Configurez les en-têtes HTTP de sécurité :
# nginx.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
API Core
Référence complète de l'API principale de TechStack.
createApp()
Crée une nouvelle instance d'application TechStack.
import { createApp } from 'techstack';
const app = createApp({
// Options de configuration
mode: 'production', // 'development' | 'production'
target: '#app', // Sélecteur CSS ou Element
strict: true, // Active le mode strict
devtools: false, // Active les DevTools
errorHandler: (err) => {
console.error('Erreur globale:', err);
}
});
component()
Enregistre un composant global.
app.component('ButtonPrimary', {
props: ['label', 'disabled'],
emits: ['click'],
template: `
<button
:disabled="disabled"
@click="$emit('click')"
class="btn-primary"
>
{{ label }}
</button>
`
});
directive()
Enregistre une directive personnalisée.
app.directive('focus', {
mounted(el) {
el.focus();
}
});
app.directive('tooltip', {
mounted(el, binding) {
el.title = binding.value;
},
updated(el, binding) {
el.title = binding.value;
}
});
// Utilisation
<input v-focus />
<button v-tooltip="'Cliquez ici'">Info</button>
Hooks
Les hooks de composition permettent de réutiliser la logique entre composants.
ref() et reactive()
import { ref, reactive } from 'techstack';
export default {
setup() {
// ref pour les primitives
const count = ref(0);
const message = ref('Hello');
// reactive pour les objets
const user = reactive({
name: 'Alice',
email: 'alice@example.com',
preferences: {
theme: 'dark'
}
});
// Accès aux valeurs
console.log(count.value); // 0
console.log(user.name); // 'Alice'
return { count, message, user };
}
};
computed()
import { ref, computed } from 'techstack';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
// Computed en lecture seule
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`;
});
// Computed avec getter et setter
const fullNameEditable = computed({
get() {
return `${firstName.value} ${lastName.value}`;
},
set(value) {
const parts = value.split(' ');
firstName.value = parts[0];
lastName.value = parts[1];
}
});
return { firstName, lastName, fullName, fullNameEditable };
}
};
watch() et watchEffect()
import { ref, watch, watchEffect } from 'techstack';
export default {
setup() {
const count = ref(0);
const user = reactive({ name: 'Alice' });
// Watch simple
watch(count, (newVal, oldVal) => {
console.log(`Count changed from ${oldVal} to ${newVal}`);
});
// Watch multiple sources
watch([count, () => user.name], ([newCount, newName]) => {
console.log(`Count: ${newCount}, Name: ${newName}`);
});
// Watch avec options
watch(
() => user.name,
(newName) => {
console.log('Name changed:', newName);
},
{
immediate: true, // Exécute immédiatement
deep: true // Watch profond pour les objets
}
);
// watchEffect - track automatique des dépendances
watchEffect(() => {
console.log(`Count is ${count.value}`);
console.log(`User is ${user.name}`);
});
return { count, user };
}
};
Hooks de cycle de vie
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'techstack';
export default {
setup() {
onBeforeMount(() => {
console.log('Component about to mount');
});
onMounted(() => {
console.log('Component mounted');
// Appels API, initialisation DOM, etc.
});
onBeforeUpdate(() => {
console.log('Component about to update');
});
onUpdated(() => {
console.log('Component updated');
});
onBeforeUnmount(() => {
console.log('Component about to unmount');
// Nettoyage : event listeners, timers, etc.
});
onUnmounted(() => {
console.log('Component unmounted');
});
}
};
Hooks personnalisés
Créez vos propres hooks pour réutiliser la logique :
// useCounter.js
import { ref } from 'techstack';
export function useCounter(initialValue = 0) {
const count = ref(initialValue);
const increment = () => count.value++;
const decrement = () => count.value--;
const reset = () => count.value = initialValue;
return {
count,
increment,
decrement,
reset
};
}
// useFetch.js
import { ref, watchEffect } from 'techstack';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(false);
const fetchData = async () => {
loading.value = true;
error.value = null;
try {
const response = await fetch(url.value);
data.value = await response.json();
} catch (e) {
error.value = e;
} finally {
loading.value = false;
}
};
watchEffect(() => {
fetchData();
});
return { data, error, loading, refetch: fetchData };
}
// Utilisation dans un composant
import { useCounter, useFetch } from './composables';
export default {
setup() {
const { count, increment } = useCounter(10);
const { data, loading, error } = useFetch(
ref('https://api.example.com/data')
);
return { count, increment, data, loading, error };
}
};
Utilitaires
Fonctions utilitaires fournies par TechStack.
nextTick()
Attendre la prochaine mise à jour du DOM :
import { ref, nextTick } from 'techstack';
export default {
setup() {
const message = ref('Initial');
const messageEl = ref(null);
const updateMessage = async () => {
message.value = 'Updated';
// Le DOM n'est pas encore mis à jour
console.log(messageEl.value.textContent); // 'Initial'
// Attendre la mise à jour du DOM
await nextTick();
// Maintenant le DOM est à jour
console.log(messageEl.value.textContent); // 'Updated'
};
return { message, messageEl, updateMessage };
}
};
provide() et inject()
Injection de dépendances pour partager des données :
// Composant parent
import { provide, ref } from 'techstack';
export default {
setup() {
const theme = ref('dark');
const updateTheme = (newTheme) => {
theme.value = newTheme;
};
// Fournir des données aux descendants
provide('theme', theme);
provide('updateTheme', updateTheme);
}
};
// Composant enfant (n'importe où dans l'arbre)
import { inject } from 'techstack';
export default {
setup() {
// Injecter les données fournies
const theme = inject('theme');
const updateTheme = inject('updateTheme');
// Avec valeur par défaut
const apiUrl = inject('apiUrl', 'https://api.default.com');
return { theme, updateTheme, apiUrl };
}
};
🎉 Félicitations!
Vous avez parcouru l'ensemble de la documentation TechStack. Vous êtes maintenant prêt à créer des applications performantes et maintenables.
Ressources supplémentaires
Pour aller plus loin avec TechStack :