Faire une bibliothèque React avec Typescript et Rollup
Table des matières
Contexte
Souvent, quand on a plusieurs projets au sein d'une même entreprise, on ne veut pas avoir à recopier les mêmes composants encore et encore lorsqu'il s'agit de choses basiques comme des boutons, des élements de formulaires, etc...
Je vais donc m'atteler à l'execice de créer une bibliothèque de composants React.
Pour cela, je vais utiliser Rollup, que j'ai déjà utilisé dans le passé pour faire un script IIFE
Création du nouveau projet
Comme la dernière fois, je commence par créer le projet et par installer les dépendances dont j'aurais besoin par la suite.
mkdir hello-react-rollup
cd hello-react-rollup/
yarn init
yarn add -D rollup rollup-plugin-typescript2 tslib typescript react react-dom
Je modifie ensuite le fichier package.json
pour y ajouter 3 points d'entrée:
- main, qui sera le chemin du fichier cjs généré
- module, qui sera le chemin du fichier esm généré
- types, qui correspond au fichier de typing généré par typescript
Je rajoute aussi le script build
pour exécuter la compilation de sources plus facilement.
Enfin, je rajoute des peerDependencies
, pour spécifier au projet qui va installer cette bibliothèque d'avoir une version identique de react
et de react-dom
{
"name": "hello-react-rollup",
"version": "1.0.0",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"license": "MIT",
"scripts": {
"build": "rollup -c"
},
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@types/react": "^17.0.20",
"react": "^17.0.2",
"rollup": "^2.56.3",
"rollup-plugin-typescript2": "^0.30.0",
"tslib": "^2.3.1",
"typescript": "^4.4.3"
}
}
Rollup
Pour que Rollup puisse fonctionner correctement, je dois créer un fichier de configuration rollup.config.js
à la racine du projet.
import typescript from 'rollup-plugin-typescript2';
import pkg from './package.json';
const input = 'src/index.ts';
const plugins = [
typescript(),
];
const external = [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {}),
];
export default [
{
input,
output: {
file: pkg.module,
format: 'esm',
sourcemap: true,
},
plugins,
external,
},
{
input,
output: {
file: pkg.main,
format: 'cjs',
sourcemap: true,
},
plugins,
external,
},
];
Ce fichier de configuration possède 2 tâches de compilations, contrairement au fichier de configuration pour le script IIFE. Les deux formats générés seront tous les deux ajoutés au projet compilé, et serviront tous les deux dans des cas bien spécifiques.
Typescript
Pour que le plugin typescript puisse fonctionner, il faut aussi que je lui fournisse un fichier de configuration tsconfig.json
:
{
"include": [
"src/**/*"
],
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"jsx": "react"
}
}
Créer un composant
Pour avoir quelque chose à compiler, je vais créer un simple composant Hello
qui retournera un template avec une chaîne de caractère Hello { name } !
.
import React from 'react'
export interface HelloProps {
name: string;
}
export const Hello = ({ name }: HelloProps) => {
return (
<div>Hello { name } !</div>
)
}
Sans oublier le point d'entrée de Rollup
export * from './components/Hello'
Et voilà, la bibliothèque React est prête à accueillir de nouveaux composants.