# Créer et publier un package npm avec esbuild, typescript et react

Type: blog post
Language: fr-FR
Canonical URL: https://simonboisset.com/blog/publish-npm-library-with-esbuild
Published: 2 octobre 2022
Summary: Introduction Personnellement j'apprécie pouvoir partager mon code avec la communauté open source. Publier des packages npm pour cela est une des principales...

## Introduction

Personnellement j'apprécie pouvoir partager mon code avec la communauté open source. Publier des packages npm pour cela est une des principales options. Mais pour s'assurer que son code soit exécutable sur n'importe quel environnement il faut certains prérequis.

La règle numéro 1 à suivre est de supporter le common js.

Pendant longtemps il fallait utiliser un bundler comme rollup, webpack ou babel.

Mais aujourd'hui une nouvelle génération de bundler arrivent, plus performants et plus faciles à paramétrer. esbuild est l'un d'eux et nous allons l'utiliser pour publier notre premier module npm.

## Initialisation

Créez un projet et initialisez le.

```bash
yarn init
```

Votre fichier package.json doit être comme ceci :

```json
{
  "name": "my-react-library",
  "version": "1.0.0"
}
```

Maintenant, installons nos librairies.

## Les dev dependencies

```bash
yarn add -D react react-dom typescript @types/react @types/react-dom
```

> Pensez à ajouter react comme peer dependency si vous souhaitez écrire une librairie react avec des hooks ou des composants.

```json
"peerDependencies": {
   "react": ">=16"
 },
```

## Typescript config

Ajoutez le fichier `tsconfig.json`.

```json
{
  "include": ["src"],
  "compilerOptions": {
    "module": "esnext",
    "target": "esnext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "declaration": true,
    "strict": true,
    "moduleResolution": "node",
    "jsx": "react",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "emitDeclarationOnly": true,
    "outDir": "dist",
    "rootDir": "src"
  }
}
```

> On n'utilise pas le compilateur typescript car nous allons utiliser esbuild pour cela. C'est pour ça que `emitDeclarationOnly` est à true

## Notre module

Maintenant, on peut écrire le module de nos envies. Voici un exemple basique.

Créez un dossier `src` puis un fichier `index.tsx`.

```tsx
export const MyComponent = () => {
  return <div>Hello word</div>;
};
```

## Build de notre librairie

On souhaite maintenant builder notre package en CJS avant de le publier.

### Configuration esbuild

Ajoutez esbuild :

```bash
yarn add -D esbuild esbuild-node-externals
```

Créez un script esbuild dans un fichier `esbuild.js` :

```js
const esbuild = require("esbuild");
const { nodeExternalsPlugin } = require("esbuild-node-externals");
esbuild
  .build({
    entryPoints: ["./src/index.ts"],
    outfile: "dist/index.js",
    bundle: true,
    minify: true,
    treeShaking: true,
    platform: "node",
    format: "cjs",
    target: "node14",
    plugins: [nodeExternalsPlugin()],
  })
  .catch(() => process.exit(1));
```

### Ajoutez la commande de build

Enfin, ajoutez le script dans le fichier package.json :

```json
 "scripts": {
    "build": "rm -rf dist && node esbuild.js && tsc"
  },
```

Maintenant, vous pouvez lancer le script :

```bash
yarn build
```

## Npm publish

> Avant de publier sur npm vous devez vous [authentifier](https://docs.npmjs.com/creating-a-new-npm-user-account)

Ajoutez ces lignes à votre package.json :

```json
 "main": "dist/index.js",
  "files": [
    "dist"
  ],
```

Puis publiez votre package :

```bash
npm publish
```

Félicitations, venez de publier votre propre librairie Typescript.

## Automatiser la publication avec les Github actions

Finalement on veut juste publier une nouvelle version quand on déclenche une action sur Github. On va donc ajouter un fichier
`.github/workflows/publish.yml`:

```yml
name: Publish
on:
  workflow_dispatch:
    inputs:
      release:
        description: "major | minor | patch"
        required: true
        default: "patch"
        type: choice
        options:
          - major
          - minor
          - patch
jobs:
  publish-new-version:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout main
        uses: actions/checkout@v2
      - name: Use Node
        uses: actions/setup-node@v1
        with:
          node-version: "14"
          registry-url: https://registry.npmjs.org/
      - name: Install dependencies
        run: yarn
      - name: Build
        run: yarn build
      - name: Publish New Version
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
        run: |
          git config --local user.email "myEmail"
          git config --local user.name "myUsername"
          yarn version --new-version ${{github.event.inputs.release}} --no-git-tag-version
          yarn publish --access public
          PACKAGE_VERSION=$(node -p "require('./package.json').version")
          git commit -a -m "v${PACKAGE_VERSION}"
          git push
```

### Ajoutez votre npm token

Pour faire fonctionner les actions on doit enregistrer un secret NPM_TOKEN.

Il faut générer un access token sur npm :

![Npm access token](https://directus.services.lezo.dev/assets/213a95c1-1ce9-45b4-bc5c-bd23c8ea2dca)


Copiez le token dans les secrets Github :
![Github action secret](https://directus.services.lezo.dev/assets/9bc983ff-e328-475b-ae4c-37799b7ee0f3)


Maintenant tout fonctionne, votre publication se fera toute seule.
![Trigger github action](https://directus.services.lezo.dev/assets/cb86ea78-a42a-43a3-b068-f513139573b7)


---

Je suis Simon Boisset, développeur fullstack freelance. Je travaille principalement avec React, React Native et Node.js. Je suis disponible pour des missions de développement ou de conseil. N'hésitez pas à me contacter sur [mon site](https://simonboisset.com/).

## Related links
- [Blog index](https://simonboisset.com/blog)
- [Website](https://simonboisset.com/)
