PURISTA: Build with rimraf, esbuild, Turbo & git-cliff
Tags: typescript, javascript, programming, opensource
Published: 2023-09-11 21:15:26

In our previous article, we laid the foundation with a glimpse of our coding setup.

It's now time to spotlight the indispensable build tools that power its development.

## rimraf

Huge thanks to [Isaacs](http://blog.izs.me/)!
[Rimraf](https://github.com/isaacs/rimraf) comes to the rescue, providing a reliable solution for deep, recursive removal of folders and files.
At PURISTA, we rely on rimraf to maintain pristine build output directories. 

## Turbo

PURISTA is organized in a monorepo.
During the development and build process, [Turbo](https://turbo.build) is used to execute different tasks and steps on multiple packages with one command.

We aren't harnessing the full potential and capabilities of Turbo at the moment since PURISTA currently requires only a few straightforward build tasks.

If you have more complex tasks, especially those with interdependencies between steps, it's worth exploring [https://turbo.build](https://turbo.build)

## Esbuild

In its early stages, PURISTA was built using the standard TypeScript compiler.
However, this approach excelled in creating CommonJS packages but turned into a nightmare when it came to generating ESM builds.

[esbuild](https://esbuild.github.io) - the rescue!
No longer struggling with configs, file extensions or similar.

With esbuild, it was becoming simple and fast.

We created a small script:
```js
const esbuild = require('esbuild')

esbuild
  .build({
    entryPoints: ['./src/index.ts'],
    outfile: './lib/esm/index.mjs',
    bundle: true,
    format: 'esm',
    splitting: false,
    platform: 'node',
    sourcemap: false,
    target: 'node18',
    minify: true,
    packages: 'external',
  })
  .catch(() => process.exit(1))

esbuild
  .build({
    entryPoints: ['./src/index.ts'],
    outfile: './lib/cjs/index.cjs',
    bundle: true,
    format: 'cjs',
    splitting: false,
    platform: 'node',
    sourcemap: false,
    target: 'node18',
    minify: true,
    packages: 'external',
  })
  .catch(() => process.exit(1))
```

Since this approach only generates JavaScript files, and we aim to provide proper TypeScript types to PURISTA users, we utilize the TypeScript compiler specifically for building types.

```
tsc --emitDeclarationOnly --declarationMap false --declaration --outDir lib/types
```

In `package.json`, only these additions were necessary:
```json
{
  "directories": {
      "lib": "lib/index.js"
  },
  "main": "./lib/cjs/index.cjs",
  "module": "./lib/esm/index.mjs",
  "exports": {
      ".": {
          "import": "./lib/esm/index.mjs",
          "require": "./lib/cjs/index.cjs",
          "types": "./lib/types/index.d.ts"
      }
  },
  "typings": "lib/types/index.d.ts",
  "files": [
      "lib"
  ]
}
```

A big thank you ❤️ to all contributors and maintainers of esbuild!
It solved the issue with CommonJS/ESM for us and produces size optimized outputs for all PURISTA packages.

## git-cliff

Changelogs are nice and everybody likes them, but nobody wants to maintain them 😜.
Here, [git-cliff](https://git-cliff.org/) by [Orhun Parmaksız](https://blog.orhun.dev) is one simple to use solution.

One simple command:
```
git-cliff > CHANGELOG.md
```
And your changelog gets generated from your git history.

Undoubtedly one of the time-saving tools, you should check out at [https://git-cliff.org](https://git-cliff.org)

---
In the upcoming article of this series, we will delve deeper into the test setup. Stay tuned!