Créer un package avec TSDX

par

Thibault

Thibault Lenclos

4 minutes de lecture

Créer un package avec TSDX

Introduction

Dans le cadre d’un partage de nombreux composants entre différents applicatifs React, nous avons réalisé une bibliothèque de composants UI et haut niveau avec l’aide du package TSDX. De la documentation aux tests, découvrez les problèmes rencontrés et leurs solutions pour rendre accessible la création de package TypeScript au plus grand nombre.

Le package TSDX est maintenu par Jared Palmer, lead open source chez Vercel, et créateur du projet https://turborepo.org/, il apporte une attention particulière à la DX et les outils dans l'écosystème JavaScript et TypeScript. D'ailleurs la promesse de cet outil est de ne pas avoir besoin de configuration et de faire marcher un ensemble d'outils efficacement et de manière transparente.

TSDX

Initialisation

Pour initialiser notre projet nous allons utiliser le template le plus complet avec React et Storybook.

npx tsdx create mylib

Cette commande va préparer un projet avec une base complète pour démarrer :

  • .github contient les scripts pour l'intégration continue avec Github actions (lint, lancer les tests, vérifier le build...)
  • example est une application React minimaliste d'exemple utilisant le bundler Parcel.
  • src est le code de votre package
  • stories contient les stories de Storybook pour faire des démos unitaires de vos composants et les documenter
  • test pour les tests Jest de votre code

Développement

Avec Storybook

Dans notre contexte de la création d'un SDK avec de nombreux composants d'UI en React, nous développons majoritairement avec Storybook (yarn storybook).

La création d'un nouveau composant implique la création d'une story associée avec plusieurs cas d'utilisations via les templates de Storybook.

Exemple pour le composant Bouton :

import React from 'react'
import { Meta, Story } from '@storybook/react'

import { Button, ButtonProps } from './'

const meta: Meta = {
  title: 'Button',
  component: Button,
  argTypes: {
    children: {
      control: {
        type: 'text',
      },
    },
  },
  parameters: {
    controls: { expanded: true },
  },
}

export default meta

const Template: Story<ButtonProps> = ({ ref, ...args }) => <Button {...args} />

export const SimpleButton = Template.bind({})
SimpleButton.args = {
  children: 'Simple button',
}

export const IconButton = Template.bind({})
IconButton.args = {
  iconOnly: true,
  icon: 'cog',
  children: <span className="u-hidden">Icon button</span>,
}

export const DisabledButton = Template.bind({})
DisabledButton.args = {
  children: 'Simple button',
  disabled: true,
}

Avec une application cliente

Il est parfois intéressant de développer les composants directement avec leur contexte d'utilisation finale.

Pour ce cas nous allons utiliser la commande link de yarn.

Dans le répertoire de la lib avec yarn link et dans le répertoire du projet avec yarn add mylib. Ces commandes vont inclure la dépendance avec un lien symbolique.

Il ne reste plus qu'à lancer les commandes de build des 2 projets (pour tsdx yarn start).

Plusieurs versions de React peuvent se retrouver incluses par votre bundler, cela a été le cas pour webpack et il a été nécessaire de forcer les dépendances avec des alias pour éviter des soucis au runtime.

const path = require('path')

module.exports = {
  //...
  resolve: {
    alias: {
      react: path.resolve(__dirname, './node_modules/react'),
    },
  },
}

Tests

Pour les tests de composants visuels, l'ajout de storyshots permet d'automatiser des tests de snapshots jest de toutes les stories dans un seul fichier test/storybook.test.tsx

import initStoryshots from '@storybook/addon-storyshots'
import { render } from '@testing-library/react'
import '@testing-library/jest-dom'

initStoryshots({
  renderer: render,
})

Pour les autres tests, l'API de Jest est très complète et permet de gérer l'ensemble des tests nécessaires pour votre package.

Documentation

Dans le contexte d'un UI kit, la documentation la plus importante est pour nous le Storybook, idéalement il peut être hébergé statiquement pour présenter aux développeurs ce qu'il est possible d'utiliser, via des cas concrets d'exemple et l'auto documentation des props.

Un fichier de README rappelant comment installer dans le projet, les commandes ou encore comment contribuer est recommandé.

Enfin nous avons mis en place plusieurs règles dans notre processus de développement et release :

Ces outils se retrouvent dans les scripts du package.json, un yarn release va automatiquement générer une nouvelle version mineure ou majeure selon l'historique des commits.

"scripts": {
        "release": "standard-version",
        "postrelease": "npm run release:tags && npm run release:github",
        "release:tags": "git push --follow-tags origin master",
        "release:github": "conventional-github-releaser -p angular"

Github release

Conclusion

L'outil TSDX a répondu à la plupart de nos attentes : démarrer un package avec des outils bien sélectionnés, un template de base complet et une documentation fournie.

Nous avons pu y ajouter facilement nos nouveaux comportements comme la compilation SASS ou encore notre processus de release. Enfin la plupart des soucis ou questionnements rencontrés avaient déjà été détaillés dans des issues Github ou noté dans la documentation de l'outil.

Continuer la discussion sur Twitter

18 avenue Parmentier
75011 Paris
+33 1 43 57 39 11
hello@premieroctet.com

Suivez nos aventures

GitHub

Naviguez à vue