Loupe

ASP.NET Core: Partage simple de composants React

Il existe de nombreuses manières de partager des composants entre plusieurs apps React (StoryBook, Lerna, registries privées npm, etc.), mais que faire si vous venez de créer 2 applications ASP.NET Core en utilisant la ligne de commande dotnet new react (Une application Front Office appelée Front et une application Back Office appelée Back par exemple) et souhaitez un moyen simple de partager des composants React entre ces 2 app ?

Et bien vous êtes sur le bon article de blog ! Voyons ensemble comment nous pouvons répondre à ce scénario en utilisant l'une des manières les plus simples qui soient !

tl;dr: Vous pourrez trouver un exemple qui fonctionne sur ce repository github

Workflow

Dans les grandes lignes, nous aurons besoin de mettre en place une librairie npm partagée (appelée shared dans cet exemple) avec son propre système de build très simple (pour transformer les fichiers TypeScript en JavaScript + Typings, etc.), et ensuite installer cette librairie dans nos applications React Front et Back pour pouvoir réutiliser nos composants.

Difficile de faire plus simple, n'est-ce pas ? Mais attendez, il existe quelques pièges sur ce parcours, donc voyons maintenant pas à pas le déroulement de ce scénario.

L'organisation des apps qui sera utilisée dans cet exemple sera la suivante :

+---Back
|   \---ClientApp
|       +---App.tsx
|       +---package.json
|       +---...
+---Front
|   \---ClientApp
|       +---App.tsx
|       +---package.json
|       +---...
+---shared
|   \---src
|       +---components
|       |   +---BlueButton.tsx
|       +---sass
|       |   +---BlueButton.scss
|       +---package.json

Initialisation de notre librairie de composants shared

Commençons par créer une nouvelle librairie npm qui se chargera de générer dans un dossier dist nos fichiers JavaScript + Typings à partir de nos fichiers TypeScript, ainsi que de copier nos fichiers de styles SASS.

À l'intérieur du dossier shared, exécutons la commande npm init pour afficher l'assistant de création d'un package npm. Les valeurs par défaut suffiront dans notre exemple, à l'exception du nom de la librairie que nous pouvons initialiser à shared. Cela devrait générer un fichier package.json pour démarrer.

Ensuite installons TypeScript (si vous souhaitez vous en servir) ainsi que React

npm i --save-dev typescript 
npm i --save-dev @types/node 
npm i --save-dev @types/react 
npm i --save react 
npm i --save react-dom

Maintenant la première étape très importante (étape trouvée grâce à mon très cher collègue Mikaël) : Modifions notre fichier package.json et déplaçons react et react-dom depuis dependencies vers peerDependencies. C'est une étape cruciale à effectuer car sinon, notre librairie shared va utiliser et embarquer sa propre version de React, ce qui va poser problème lors de l'utilisation depuis les applications Front et Back car comme vous le saviez peut-être déjà, React n'aime pas être en double... Nous devrions avoir quelque chose de similaire :

"peerDependencies": {
  "react": "^16.0.0",
  "react-dom": "^16.0.0"
},

Nous aurons également besoin d'ajouter un fichier tsconfig.json pour la compilation TypeScript, par exemple :

{
    "compilerOptions": {
        "jsx": "react",
        "declaration": true,
        "outDir": "./dist/",
        "esModuleInterop": true,
        "moduleResolution": "node",
        "rootDir": "./src"
    },
    "include": [
        "src/**/*"
    ]
}

Maintenant, la seconde étape la plus importante (selon moi) est d'ajouter quelques petits scripts NPMpour faciliter le processus de génération de notre package shared. Modifions le fichier package.json pour lui ajouter les scripts copy-sass (pour copier nos fichiers SASS), build-ts (pour générer nos fichiers JavaScript + Typings depuis nos fichiers TypeScript) et build (qui va se contenter d'appeler les 2 scripts précédents) :

"scripts": {
  "copy-sass": "(robocopy src dist *.scss /E) ^& IF %ERROR_LEVEL% LEQ 1 exit 0",
  "build-ts": "tsc",
  "build": "npm run copy-sass && npm run build-ts",
  "test": "echo \"Error: no test specified\" && exit 1"
},

Ça y est, nous pouvons enfin ajouter un composant React avec son fichier SASS et générer notre package en utilisant la commande npm run build.

Référencer notre librairie de composants shared

OK, attention ! Préparez vous pour une étape très compliquée ! ... Bon d'accord je plaisante

Faisons cela en 3 étapes simples :

Se déplacer dans le dossier ClientApp (de notre application Front ou Back par exemple), puis exécuter la commande npm i PATH_TO_YOUR_SHARED_FOLDER, exemple :

CD Front\ClientApp
npm i ../../shared

Typescript

Pour utiliser notre composant depuis le fichier Home.tsx par exemple, nous avons simplement besoin de l'importer de la manière suivante :

import BlueButton from "shared/dist/components/BlueButton";

Puis ensuite rajouter notre composant dans la section render() :

export class Home extends Component {
  render() {
    return (
      <div>
	    ...
        <BlueButton />
        ...
      </div>
    );
  }
}

Note : il est nécessaire de référencer la version compilée du code (c'est à dire le dossier dist), et surtout ne pas référencer le code source directement (c'est à dire le dossier src) car c'est notamment le fameux scénario qui pose beaucoup de soucis dans une app React créée via create-react-app sans éjecter la config :) (Je vous laisse parcourir les nombreux articles sur internet qui relatent du sujet).

SASS

Pour utiliser notre fichier SASS, nous pouvons le référencer tout simplement depuis notre fichier App.scss de la manière suivante:

@import "shared/dist/sass/BlueButton";

Et voilà! Notre composant a été installé avec succès !

01-aspnetcore-react-shared-components-ui.PNG

Workflow de développement

Avec tout ça en place, vous devez vous souvenir que pour chaque modification d'un composant de la librairie shared, il sera nécessaire de regénérer le package avec la commande npm run build.

La bonne nouvelle, c'est que l'app se recharge automatiquement lorsque vous le faite :

02-aspnetcore-react-shared-components-development-hot-reloading.gif

En conclusion

C'est la fin de ce petit article concernant la mise en place d'un système simple de partage de composants entre 2 applications React hébergées dans une application aspnetcore (et plus particulièrement initialisée avec create-react-app).

Bien entendu, suivant la taille de votre projet ou si vous avez besoin de partager ces composants avec de nombreuses applications, les autres solutions mentionnées dans le début de cet article constitueront probablement une bonne piste.

Dans tous les cas, j'espère que cet article a pu vous aider d'une manière ou d'une autre. N'hésitez pas à me contacter sur Twitter @vivienfabing ou dans les commentaires, et que le code soit avec vous !

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus