Bonjour !
Aujourd’hui un petit article pour vous montrer comment avec Nuxt3 faire du rendu coté serveur sans serveur 🤯
Je pars du principe que vous êtes habitué à NodeJs et qu’il est installé.
PS: N’hésitez pas à donner votre avis sur le discord, si vous voyez une coquille n’hésitez pas à la remonter 😋
# Qu’est ce que Nuxt
Il y a encore pas si longtemps je voyais Nuxt3 d'un mauvais oeil pour plein de raison technique, mais maintenant Nuxt3 est en bonne phase 😁
Nuxt est décrit comme “le framework vue hybride” sur la page principale
Pour faire une analogie il est à VueJs ce que Next est à react ou encore SvelteKit à Selvte.
Si vous faites du vue3 mais que vous ne connaissez pas nuxt je vous conseille d’y jeter un oeil 😉
En gros les points forts de Nuxt:
- plusieurs modes de rendu
- server side rendering
- static site generation
- single page app
- mode hybride (pas encore dispo en RC11)
- auto import (
composable
,components
,layouts
) - Configuration automatique de vue-router via l’arborescence des dossiers
pages
etlayouts
- système de
plugins
&modules
# Installation de Nuxt (et de quelques autres trucs)
# installation de Nuxt
si jamais voici le lien de la doc de nuxt.
pnpm dlx nuxi init mon-super-project
Et on crée un fichier .npmrc
où l’on va mettre shamefully-hoist=true
(plus d’info au pourquoi du comment ici)
# Quelques autres trucs
On installe un linter, avec la config d’Antfu parce que j’aime bien cette configuation, en gros un linter c’est un outil qui te gueule dessus si y’a une virgule en trop ou en moins ou bien si y’a un console.log (pas exemple).
par exemple avec l’extension eslint sur vscode
pnpm -D i @antfu/eslint-config eslint typescript
Le package.json doit ressembler à un truc comme ça:
{ "private": true, "scripts": { "build": "nuxt build", "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare" }, "devDependencies": { "@antfu/eslint-config": "^0.27.0", "eslint": "^8.23.1", "nuxt": "3.0.0-rc.11", "typescript": "^4.8.3" } }
package.json
Et puis bah c’est bien beau d’installer des packages mais faut il encore les utiliser 😋
On crée un fichier .eslintrc
à la racine du projet:
{ "extends": "@antfu" }
.eslintrc
# Un peu de code
# vue-router et app.vue
Pour activer vue-router dans Nuxt3 il suffit de créer un dossier pages
, on va créer un fichier index.vue
dedans:
<script setup> const { data } = await useAsyncData(() => new Date().toLocaleString()) </script> <template> <div> bienvenue sur l'index, on est le {{ data }} </div> </template>
pages/index.vue
Rien de bien compliqué, on demande au serveur une date, plus qu’à dire à Nuxt d’utiliser les pages: il suffit de modifier app.vue
.
<template> <div> <NuxtPage /> </div> </template>
app.vue
Si maintenant je vais sur http://localhost:3000/ j’ai bien bienvenue sur l'index, on est le 24/09/2022, 14:16:00
Si par contre à la place je vais sur http://localhost:3000/page/qui/n/existe/pas j’ai bien une page d’erreur 404
# NitroJs, le moteur qui fait vroum vroum
NitroJs est le moteur utilisé par Nuxt (et développé pour à la base), il permet de deployer votre code pour divers acteurs du cloud (Google, Amazon, Heroku, Netlify, etc…) je vais utiliser le deployment sur firebase qui est un produit Google, mais vous pouvez utiliser un autre acteur du cloud.
# Ajout des dépendances
Toujours avec pnpm chez moi
pnpm install -D firebase-admin firebase-functions firebase-functions-test
et firebase-tools
en global avec npm cette fois car c’est un binaire qu’on installe globallement :
npm install -g firebase-tools
# Création d’un compte sur firebase et d’un projet
Bon je vous avous j’ai un peu la flemme de recréer un compte pour vous montrer comment ça marche mais c’est super simple, faut juste une carte bancaire (Google offre 300$ de crédit pour les 3 mois suivant, de quoi tester Google Cloud Platform)
Une fois le projet créé (je vous assure y’en a pour 3 minutes chrono en main) il faut changer le type de facturation en Blaze pour pouvoir utiliser les clouds functions, c’est une formule où vous payez que ce que vous consommez.
Les (tarifs) sont vraiment simples à comprendre et très accessible même à une large échelle, ça vous coutera bien moins cher qu’un VPS à titre d’exemple.
# firebase.json
Il n’y a plus qu’à créer un fichier firebase.json
à la racine du projet :
{ "functions": { "source": ".output/server" }, "hosting": [ { "site": "<votre_id_de_projet>", "public": ".output/public", "cleanUrls": true, "rewrites": [ { "source": "**", "function": "server" } ] } ] }
firebase.json
En remplacant la clef hosting.site
par votre id de projet (pour moi test-nuxt3-faas
) :
# Login sur firebase
Pour se connecter il suffit de lancer firebase login
, cela va vous ouvrir un nouvel onglet dans votre navigateur avec une page de connexion google classique.
# Deployment
il n’y a plus que deux commandes à faire:
pnpm run build
pour générer le dossier.output
firebase deploy --project <votre_id_de_projet>
pour deployer chez Google
.output/server
et relancer un npm i
.Plus d'info ici.
Maintenant si je vais sur https://test-nuxt3-faas.web.app/ j’ai bien bienvenue sur l'index, on est le 9/25/2022, 10:31:03 AM
, alors oui, je sais … Le formatage est en Anglais, c’est normal la fonction à été deployée dans la région us-central1 du coup on a une locale en_US et si on va sur https://test-nuxt3-faas.web.app/blablabla on a bien la page 404 😉.
# Bonus: avoir la bonne locale
On va utiliser le package negociator pour deviner la locale à utiliser
pnpm i negociator pnpm i -D @types/negociator
Et on l’utilise
<script setup> import Negotiator from 'negotiator' const { data } = await useAsyncData(({ ssrContext }) => { if (process.server) { const negotiator = new Negotiator(ssrContext.event.req) const locale = negotiator.language(['fr-FR', 'en-US']) return new Date().toLocaleString(locale) } return new Date().toLocaleString() }) </script> <template> <div> bienvenue sur l'index, on est le {{ data }} </div> </template>
pages/index.vue
Si je met le navigateur en Anglais j’ai bienvenue sur l'index, on est le 9/25/2022, 11:09:25 AM
et en Français j’ai bienvenue sur l'index, on est le 25/09/2022 11:12:54
and voilà !