Simplify TypeScript builds with esbuild and skip tsc/tsx
Tags: node, typescript, javascript, webdev
Published: 2023-08-09 07:49:22

The JavaScript ecosystem constantly undergoes innovations. One of the more recent game-changers is esbuild, a lightning-fast JavaScript and TypeScript bundler. Unlike traditional TypeScript compilers like tsc, esbuild offers rapid compile times and a straightforward configuration. This post will delve into using esbuild to handle TypeScript compilation, emphasizing the vast array of parameters it offers.

## Why esbuild over tsc?

- **Performance**: esbuild leverages Go's performance benefits, offering incredibly fast bundling times compared to other bundlers and compilers.
- **Simplicity**: esbuild's configuration is relatively straightforward, making it easy to integrate into existing projects.
- **Flexibility**: esbuild provides various options, like the ability to output to different formats, set the platform target, and more.


![esbuild running in watch mode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/461fh8uqnj6pl8hnv3wg.png)
<figcaption>Running esbuild in watch mode will allow you to use the same tool for production and development, without sacrificing performance!</figcaption>

## Configuring esbuild for TypeScript

Firstly, ensure esbuild is part of your project:

```bash
npm install esbuild --save-dev
```

Here's our proposed NPM script configuration using esbuild:

```json
{
    "scripts": {
        "build": "esbuild `find src \\( -name '*.ts' \\)` --platform=node --target=esnext --outdir=build --format=cjs",
        "build:watch": "npm run build -- --watch",
        "start": "node build | npx pino-pretty",
        "start:watch": "node --watch -r dotenv/config build | npx pino-pretty",
        "dev": "concurrently \"npm:build:watch\" \"npm:start:watch\""
    }
}

```

esbuild Parameters Explained:

1. 
**Input Files**: The `find src \\( -name '*.ts' \\)` portion locates all TypeScript files within the src` `directory, feeding them to esbuild.

2. 
**platform**: The `--platform=node` flag ensures the code is compatible with a Node.js environment. Other possible values include `browser` for browser-specific output.

3. 
**target**: With `--target=esnext`, we instruct esbuild to output the latest version of ECMAScript. This is invaluable when you want to leverage the latest language features. Other values could be `es6`, `es2016`, etc., depending on your needs.

4. 
**outdir**: The `--outdir=build` option specifies the output directory for our compiled files. Replace `build` with any directory name of your choosing.

5. 
**format**: The `--format=cjs` command dictates the module system to be used. We've chosen CommonJS (`cjs`) here, but esbuild also supports `esm` (ES Modules), `iife`, and more.

6. 
**watch**: Adding `--watch` makes esbuild monitor file changes and recompile as necessary. This is invaluable during development, negating the need to manually trigger recompiles.

7. 
**Concurrently**: Not an esbuild parameter, but vital for our setup. `concurrently` runs multiple commands concurrently. In our script, it allows us to watch and build, and then run our application simultaneously.

## Reaping the Rewards of esbuild

1. 
**Bypass tsc/tsx**: Transitioning to esbuild means a direct reduction in compile times.

2. 
**Simplified Build Pipeline**: The amalgamation of bundling and compiling under a single tool, esbuild, streamlines our pipeline.

3. 
**Parameter-Driven Configuration**: esbuild's parameters allow developers to easily craft a build process tailored to their specific requirements.

## Wrapping Up
esbuild's emergence as a go-to TypeScript compiler promises faster development cycles and simplified build processes. Its array of parameters allows fine-grained control over the build, catering to a myriad of configurations. If you haven't yet, now might be the time to consider the switch from traditional `tsc` compilation. Happy building!