Améliorer l'intégration avec Unplugin et Nuxt Module
Avoir une bibliothèque de composants robuste est un excellent point de départ, mais l'intégrer dans l'écosystème Vue.js passe à un autre niveau. Dans cet écosystème, deux outils principaux se démarquent :
- Unplugin Vue Components : Un plugin de bundler pour des composants à la demande qui sont auto-importés, entièrement typés et tree-shakable.
- Nuxt : Un framework open-source basé sur Vue.js qui simplifie et dynamise le développement web.
Bien que notre bibliothèque de composants puisse fonctionner sans intégration à ces outils, je suis fermement convaincu que l'intégration renforcera sa puissance et sa facilité d'utilisation. Je suis dévoué à offrir la meilleure expérience développeur possible, et je suis sûr que vous la trouverez inestimable.
Résolveur de Composants Unplugin Vue
Avant de construire le résolveur, il est essentiel de comprendre comment Unplugin Vue Components fonctionne. Cela clarifiera ce que fait un résolveur et sa fonctionnalité.
Tip
Si vous avez des questions, n'hésitez pas à commenter ci-dessous, et je serai heureux de vous aider.
Considérez ce composant :
<script lang="ts" setup>
</script>
<template>
<UButton label="Cliquez sur moi" />
</template>
Remarquez qu'il n'y a pas de déclaration d'importation pour le composant UButton
. Unplugin Vue Components passe au crible le template et identifie les balises HTML non standards pour les trouver dans sa liste de composants. Cette liste peut être alimentée manuellement ou automatiquement peuplée à l'aide d'un résolveur.
Un résolveur est une fonction qui reçoit un nom de composant et retourne son chemin d'importation s'il correspond à la liste interne du résolveur. Cela permet l'auto-importation sélective des composants ou l'ajout de préfixes aux noms de composants.
Dans notre exemple, un résolveur pourrait résoudre le composant UButton
comme suit :
return {
name: 'Button',
from: '@nuxt/ui'
}
Unplugin Vue Components transformerait le composant en injectant la déclaration d'importation :
<script lang="ts" setup>
import { Button as UButton } from '@nuxt/ui'
</script>
<template>
<UButton label="Cliquez sur moi" />
</template>
Simple, non ? Maintenant, construisons notre résolveur.
Note
Pour approfondir votre compréhension de Vite, essayez le vite-plugin-inspector, qui vous permet d'inspecter les modifications apportées par chaque plugin.
Construction du Résolveur
Tout d'abord, rassemblez tous vos composants de bibliothèque dans un fichier src/components.ts
au sein du dossier packages/huchet-vue
:
touch src/components.ts
Puis exportez un tableau de tous les composants :
export const components = [
'Button'
]
Pour garantir des mises à jour, créez un test qui vérifie que les composants exportés correspondent à ceux du dossier components
. Créez un fichier src/index.test.ts
dans packages/huchet-vue
:
touch src/index.test.ts
Ajoutez ce test pour vérifier les exports de composants :
import { expect, it } from 'vitest'
import { components } from './components'
import * as Huchet from './index'
it('doit exposer les bons composants', () => {
expect(Object.keys(Huchet)).toEqual(Object.values(components))
})
Ce test empêche les mises à jour manquées lorsque les composants changent.
Note
Inspiré par Radix Vue.
Ensuite, créez un src/resolver.ts
pour le résolveur Unplugin Vue Components et installez-le en tant que dépendance de développement :
touch src/resolver.ts && pnpm add -D unplugin-vue-components
La fonction du résolveur s'initie dans vite.config.ts
, permettant aux développeurs de passer des options comme un préfixe pour les noms des composants. Elle résout les noms des composants et retourne les chemins d'importation s'ils correspondent :
import type { ComponentResolver } from 'unplugin-vue-components'
import { components } from './components'
export interface ResolverOptions {
/**
* préfixe pour les composants utilisés dans les templates
*
* @defaultValue ""
*/
prefix?: string
}
export default function (options: ResolverOptions = {}): ComponentResolver {
const { prefix = '' } = options
return {
type: 'component',
resolve: (name: string) => {
if (name.toLowerCase().startsWith(prefix.toLowerCase())) {
const componentName = name.substring(prefix.length)
if (components.includes(componentName)) {
return {
name: componentName,
from: '@barbapapazes/huchet-vue',
}
}
}
},
}
}
Pour garantir que le résolveur soit construit, ajoutez-le comme point d'entrée dans vite.config.ts
:
import { resolve } from 'node:path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
entry: {
index: resolve(__dirname, 'src/index.ts'),
resolver: resolve(__dirname, 'src/resolver.ts'),
},
},
},
})
Enfin, exportez le résolveur dans package.json
:
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs"
},
"./resolver": {
"types": "./dist/resolver.d.ts",
"import": "./dist/resolver.mjs"
}
},
"main": "./dist/index.mjs",
"types": "dist/index.d.ts"
}
Note
Reconstruisez le projet pour vous assurer que le nouveau point d'entrée est accessible.
Utilisation du Résolveur
Avec le résolveur prêt, testons-le dans notre projet de playground :
- Accédez au dossier de playground :
cd ../../playground/vue
- Installez
unplugin-vue-components
:
pnpm add -D unplugin-vue-components
- Mettez à jour
vite.config.ts
pour utiliser le résolveur avec un préfixeU
:
import HuchetVueResolver from '@barbapapazes/huchet-vue/resolver'
import Vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
Vue(),
Components({
dts: true,
resolvers: [
HuchetVueResolver({
prefix: 'U'
}),
],
})
],
})
- Ajoutez
components.d.ts
à.gitignore
:
echo "components.d.ts" >> .gitignore
Note
Ce fichier est généré par unplugin-vue-components
pour aider votre IDE à comprendre les composants et à fournir une auto-complétion.
- Mettez à jour
src/App.vue
pour utiliser le composantUButton
sans l'importer :
<template>
<div class="flex gap-6 p-6">
<UButton label="Hello World" />
<UButton label="Hello World" variant="outline" />
</div>
</template>
Voilà ! Le composant UButton
est automatiquement importé pour plus de facilité d'utilisation.
Module Nuxt
Nuxt transforme le développement web avec Vue.js en fournissant une configuration étendue et un système de modules. Construire un module Nuxt pour notre bibliothèque de composants nécessite peu d'efforts et élimine la configuration pour les développeurs. Plongeons-y.
Construction du Module
Commencez par créer un fichier nuxt.ts
dans le dossier packages/huchet-vue
:
touch nuxt.ts
Installez les paquets Nuxt nécessaires ainsi que Tailwind CSS :
pnpm add -D @nuxt/kit @nuxt/schema && pnpm add tailwindcss@next @tailwindcss/vite@next @tailwindcss/postcss@next
Ensuite, créez le module :
import type { } from '@nuxt/schema' // Obligatoire pour éviter un bug lors de la construction
import { addComponent, addVitePlugin, defineNuxtModule } from '@nuxt/kit'
import { components } from './components'
export interface ModuleOptions {
prefix: string
}
export default defineNuxtModule<ModuleOptions>({
meta: {
name: '@barbapapazes/huchet-vue',
configKey: 'huchet',
compatibility: {
nuxt: '>=3.0.0',
},
},
defaults: {
prefix: '',
},
async setup(options, nuxt) {
if (nuxt.options.builder === '@nuxt/vite-builder') {
const Tailwind = await import('@tailwindcss/vite').then(r => r.default)
addVitePlugin(Tailwind())
}
else {
nuxt.options.postcss.plugins['@tailwindcss/postcss'] = {}
}
for (const component of components) {
addComponent({
name: `${options.prefix}${component}`,
export: component,
filePath: '@barbapapazes/huchet-vue',
})
}
},
})
Ce plugin simplifie la configuration de Tailwind CSS, utilisant soit Vite soit PostCSS en fonction du constructeur Nuxt.
La deuxième partie auto-importe les composants dans le système Nuxt en utilisant le framework Unimport, permettant la personnalisation des préfixes comme le résolveur Unplugin Vue Components.
Inspiré par Radix Vue Nuxt module et Nuxt UI 3 module.
Ajoutez une entrée dans vite.config.ts
et exportez-la dans package.json
:
import { resolve } from 'node:path'
export default defineConfig({
build: {
lib: {
entry: {
index: resolve(__dirname, 'src/index.ts'),
resolver: resolve(__dirname, 'src/resolver.ts'),
nuxt: resolve(__dirname, 'src/nuxt.ts'),
},
},
rollupOptions: {
external: ['vue', '@nuxt/kit', '@tailwindcss/vite'],
},
},
})
Assurez-vous d'externaliser @nuxt/kit
et @tailwindcss/vite
.
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs"
},
"./resolver": {
"types": "./dist/resolver.d.ts",
"import": "./dist/resolver.mjs"
},
"./nuxt": {
"types": "./dist/nuxt.d.ts",
"import": "./dist/nuxt.mjs"
}
},
"main": "./dist/index.mjs",
"types": "dist/index.d.ts"
}
Utilisation du Module
Avec le module Nuxt en place, mettons en place un moyen de tester sa fonctionnalité. Nous allons créer un nouveau playground Nuxt, installer le package et le configurer.
- Créez un nouveau projet Nuxt depuis le répertoire racine :
npx nuxi init ./playground/nuxt
Note
Modifiez le script postinstall
en dev:prepare
dans le package.json
de Nuxt pour éviter les erreurs après une installation de package. Renommez-le car prepare
est réservé par npm.
- Installez la bibliothèque de composants :
cd ./playground/nuxt && pnpm add ../../packages/huchet-vue
- Dupliquez le
App.vue
du playground Vue vers le playground Nuxt :
cp ../vue/src/App.vue ./app.vue
- Ajoutez le module dans
nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['@barbapapazes/huchet-vue/nuxt'],
css: ['~/assets/css/main.css'],
huchet: {
prefix: 'U',
},
compatibilityDate: '2024-11-01',
devtools: { enabled: true },
})
Note
Incluez le fichier CSS en utilisant la propriété css
pour faire fonctionner Tailwind CSS.
- Créez le fichier CSS dans
assets/css/main.css
:
mkdir -p assets/css && touch assets/css/main.css && echo "@import 'tailwindcss';" >> assets/css/main.css
- Lancez le projet Nuxt :
pnpm dev
Voila ! Vous pouvez désormais utiliser la bibliothèque de composants dans un projet Nuxt de manière fluide, avec des composants auto-importés et un Tailwind CSS pleinement fonctionnel.
L'expérience développeur Nuxt, enrichie par le système de modules, simplifie considérablement la vie des développeurs. Je suis sûr que vous l'apprécierez aussi.
Merci de me lire ! Je m'appelle Estéban, et j'adore écrire sur le développement web.
Je code depuis plusieurs années maintenant, et j'apprends encore de nouvelles choses chaque jour. J'aime partager mes connaissances avec les autres, car j'aurais aimé avoir accès à des ressources aussi claires et complètes lorsque j'ai commencé à apprendre la programmation.
Si vous avez des questions ou souhaitez discuter, n'hésitez pas à commenter ci-dessous ou à me contacter sur Bluesky, X, et LinkedIn.
J'espère que vous avez apprécié cet article et appris quelque chose de nouveau. N'hésitez pas à le partager avec vos amis ou sur les réseaux sociaux, et laissez un commentaire ou une réaction ci-dessous—cela me ferait très plaisir ! Si vous souhaitez soutenir mon travail, vous pouvez me sponsoriser sur GitHub !