ReactNext.jsArchitectureTypeScript

Découper le travail en front-end : front of front-end et back of front-end

Publié le

Dimitri Dumont
Dimitri Dumont

Développeur React & Next.js freelance

Depuis quelques années, j'ai l'habitude de découper le développement d'un projet front-end en deux parties : la partie UI et la partie des données.

L'objectif de cet article est de vous présenter cette pratique et les bénéfices qu'elle peut apporter à vos projets front-end lorsqu'on sépare la partie visuelle de la partie logique. Pour éviter tout malentendu, comprenez bien que cette pratique n'est en aucun cas une obligation ou une pratique à mettre en place dans tous les projets front-end.

Schéma sur la méthode de travail front of front-end et back of front-end

Au-delà des préférences de chaque développeur, cette pratique a plusieurs avantages :

  • Permettre à des développeurs plus juniors d'intervenir sur des projets : ce développeur pourra travailler uniquement sur la partie UI (ex : créer des composants React et les styliser) tandis qu'un développeur plus expérimenté pourra implémenter la logique via Redux, implémenter l'API, etc.
  • Permettre à chaque partie (UI & logique) de travailler indépendamment : dans un premier temps, le développeur qui travaille sur les composants React n'a pas besoin de l'API, ni même de la partie logique. De même pour le développeur qui intègre la partie logique, il n'a pas besoin d'ouvrir son navigateur pour développer les fonctionnalités.
  • Permettre à de nouveaux développeurs d'être très vite productifs sans même avoir tout de suite les connaissances sur les règles métiers.
  • Elle permet de découper correctement un projet front-end en séparant la logique métier de la partie visuelle.

Elle découle de l'utilisation des bonnes pratiques de développement. Voici les pré-requis pour comprendre l'intérêt de cette méthode de travail :

L'évolution des applications et des technologies web

Avant d'expliquer comment mettre en place cette approche, il faut comprendre pourquoi j'en suis venu à l'utiliser. Si vous êtes développeur, vous devez savoir que les technologies évoluent rapidement, c'est l'une des raisons pour laquelle les langages de programmation, les frameworks et les librairies évoluent également rapidement.

Il y a une dizaine d'années, les sites internet étaient assez simples et étaient principalement développés en HTML et CSS. Puis Javascript a commencé à être utilisé pour dynamiser l'affichage de ces sites internet. Ensuite, Javascript a vu son utilisation évoluer pour mettre à jour dynamiquement des données dans une page web sans avoir besoin de la recharger.

De fil en aiguille, c'est ainsi que nous avons commencé à utiliser des librairies comme React et des frameworks comme Next.js pour développer des sites internet, des applications web et mobiles.

Désormais, la plupart des projets front-end a un minimum de logique. Que ce soit pour gérer des formulaires, gérer des étapes avant l'envoi des données à une API, etc. Les personnes qui pensent que le développement front-end consiste simplement à intégrer des maquettes n'ont pas réellement la connaissance des projets web de nos jours.

Complexité des applications web de nos jours

Il existe toujours des sites vitrine ou "one page" avec assez peu de logique qui peuvent toujours être développés uniquement en HTML & CSS. Mais la réalité est qu'une grande partie des applications contiennent des fonctionnalités qui impliquent un certain degré de complexité. Par exemple, un site vitrine avec des données statiques n'a pas la même complexité qu'un réseau social avec un système d'abonnement, de modération, de messagerie, etc.

Avec toutes les applications web de nos jours et leurs fonctionnalités, la partie front-end d'une application web est de plus en plus complexe. Il n'est pas rare de voir des centaines de composants React, plusieurs dizaines de hooks, des actions et des reducers Redux, etc. On parle même d'architecture hexagonale, de "DDD", et de tests en front-end.

Inversion de dépendances, architecture hexagonale & tests

Étant donné que les projets front-end sont de plus en plus complexes, il est intéressant de s'assurer de la qualité de code et que chaque modification de ce code ne génère pas de régression. C'est pour cela que de plus en plus de développeurs front-end s'intéressent à l'inversion de dépendances, l'architecture hexagonale et les tests pour développer des projets plus robustes et plus rapidement.

Si vous ne connaissez pas ces sujets, je vous invite à lire mes articles sur l'inversion de dépendances en front-end et l'architecture hexagonale en front-end. J'y propose ma vision de ces pratiques avec des exemples concrets sur des projets React & Next.js.

En appliquant ces bonnes pratiques dans vos applications web, le découpage de la partie visuelle et des données devient naturel. La partie UI est un des clients de la partie logique, c'est-à-dire que ça peut être des composants React, des composants Vue.js, du simple Javascript, une CLI, etc. Ainsi, même si un seul développeur peut s'occuper de développer les deux parties, il peut être intéressant de partager ce travail entre plusieurs développeurs. C'est également un gain de productivité lorsqu'un développeur intervient sur une partie où il a plus de compétences et de connaissances.

Par exemple, un développeur peut avoir plus d'appétences sur les notions d'UI/UX et d'accessibilité, tandis qu'un autre aura plus d'appétences sur l'architecture de code, les bonnes pratiques de développement et les tests. Ainsi, lorsque plusieurs développeurs interviennent sur un même projet, ils peuvent se répartir naturellement les tâches en fonction de leurs compétences et de leurs appétences.

Exemple concret en React et Next.js

Afin de vous donner un exemple concret, voyons comment développer une fonctionnalité avec cette méthode de travail sur un projet en TypeScript avec React et Next.js. Pour cela, je vais développer une page qui regroupe une liste d'articles de blog. Ces articles de blog sont récupérés via une API externe. Cette fonctionnalité est volontairement simple afin de se focaliser sur la méthodologie.

Voici comment j'organise mes projets React et Next.js :

  • Un dossier src/app qui contient les pages, layouts et autres éléments liés à Next.js
  • Un dossier src/ui qui contient les composants React et le style
  • Un dossier src/modules qui contient la logique du projet front-end

1. Partie visuelle

Le développeur en charge de la partie visuelle va travailler sur la création de la page Next.js ainsi que ses composants. Il va également intégrer le style, ici avec TailwindCSS. Dans des cas plus complexes, il pourrait intégrer des animations et d'autres éléments visuels.

src/app/blog/page.tsx
import { BlogList } from "@/ui/components/blog/blog-list"
import { Container } from "@/design-system/blog-article/layout/container"
import { Title } from "@/design-system/blog-article/title"
import { NextPage } from "next"
 
const BlogPage: NextPage = () => {
	return (
		<Container as="div">
			<Title>Découvrez mes articles</Title>
 
			<p className="text-shark-500 text-md mt-4">
				Je partage mes expériences et mes connaissances en tant que
				développeur front-end sur les bonnes pratiques de
				développement, TypeScript, React & Next.js
			</p>
 
			<hr className="my-10 border-shark-200" />
 
			<BlogList />
		</Container>
	)
}
 
export default BlogPage
src/ui/components/blog/blog-list.tsx
import { ArticlePreviewItem } from "@/ui/components/blog/article-preview-item"
import { getBlogPosts } from "@/modules/blog/get-blog-posts.action"
 
export const BlogList = async () => {
	const blogPosts = await getBlogPosts()
 
	return (
		<div className="space-y-10 pb-8">
			<div className="grid md:grid-cols-2 gap-10 mb-10">
				{blogPosts?.map((post, i) => (
					<div
						key={i}
						className="max-md:border-b last-of-type:border-none border-shark-100 pb-8"
					>
						<ArticlePreviewItem {...post} />
					</div>
				))}
			</div>
		</div>
	)
}
src/ui/components/blog/article-preview-item.tsx
import { twMerge } from "tailwind-merge"
import { Avatar } from "@/design-system/blog-article/avatar"
import Link from "next/link"
import { BlogPost } from "@/modules/blog/blog.type"
import Image from "next/image"
 
type Props = BlogPost
 
export const ArticlePreviewItem = ({
	author,
	description,
	publicationDate,
	title,
	slug,
	cover,
}: Props) => {
	return (
		<Link href={"/blog/" + slug} className="flex flex-col group">
			<div className="relative rounded-sm overflow-hidden aspect-video bg-shark-100 mb-3">
				<Image
					src={cover ?? "/img/blog/default-article-banner.png"}
					alt={cover + " cover"}
					fill
					className="object-contain"
					quality={50}
					sizes="100%"
				/>
			</div>
			<article>
				<h2
					className={twMerge(
						ClashDisplay.className,
						"word-spacing text-xl font-medium group-hover:text-shark-600 transition-all duration-150 line-clamp-2",
					)}
				>
					{title}
				</h2>
				<div className="text-shark-400 text-xs mt-2">
					{publicationDate}
				</div>
				<p className="my-6 text-sm leading-6 text-shark-600 line-clamp-3">
					{description}
				</p>
 
				<div className="flex items-center space-x-4">
					<Avatar
						avatar={author.avatar}
						name={author.name}
						size={"sm"}
					/>
					<div className="space-y-1">
						<div className="text-sm">{author.name}</div>
						<div className="text-xs text-shark-500">
							{author.job}
						</div>
					</div>
				</div>
			</article>
		</Link>
	)
}

Imaginons que le développeur en charge de la partie visuelle intervienne en premier, il peut très bien utiliser de fausses données le temps que l'autre développeur ou lui-même s'occupe de la récupération des articles.

Ainsi, il n'est pas bloqué pour développer cette partie et n'a pas besoin de connaissances et de compétences autres que sur React, TailwindCSS et Next.js.

2. Partie logique

Pour le développement de la partie logique, je vais créer une fonction getBlogPosts qui sera utilisée par l'UI, dans des composants React.

src/modules/blog/get-blog-posts.ts
export const getBlogPosts = async () => {
	const response = await fetch("https://api.example.com/blog-posts")
 
	if (!response.ok) {
		throw new Error("Failed to fetch blog posts")
	}
 
	const blogPosts = await response.json()
 
	return blogPosts
		.filter((blogPost) => blogPost.isPublished)
		.sort(
			(a, b) =>
				new Date(b.publicationDate).getTime() -
				new Date(a.publicationDate).getTime(),
		)
}

L'avantage de découper ainsi, c'est qu'il n'est pas nécessaire d'ouvrir le navigateur pour vérifier si les articles de blog sont correctement récupérés. Grâce aux tests automatiques avec Jest, on peut le vérifier facilement et rapidement sans React.

Conclusion

En adoptant la pratique du "front of front-end" et du "back of front-end", on facilite la collaboration entre les développeurs front-end en offrant une plus grande autonomie dans le développement et en accélérant la productivité des nouveaux arrivants.

Cette approche structurée permet de mieux gérer la complexité croissante des applications web, garantissant ainsi des solutions robustes et évolutives.

Comme chaque outil et méthode de travail, elle est à utiliser lorsque c'est nécessaire et selon votre contexte.

Cet article vous a été utile ?

Je peux vous accompagner sur votre projet React & Next.js.

Discutons de votre projet →

Articles similaires