One of the most interesting things about building an api in Node is the fact that we can choose the tooling we want to use or experiment with. And one of the things we can choose is our compiler, in the case of this article we will be interested in transpiling transpiling the code from TypeScript to JavaScript in a quick way during the development process. Just like we want to have that quick build to use in our production environment.
To be honest, I'm a big fan of SWC, but I had no idea that there were dependencies that help us configure a project with esbuild in a super fast and simple way. It's so easy but so easy, to the point that we can make the migration from babel to esbuild in the blink of an eye.
Project Setup
First let's start with the usual one, which is to create the project folder:
mkdir ts-esbuild
cd ts-esbuild
Next, initialize a TypeScript project and add the necessary dependencies:
npm init -y
npm install -D typescript @types/node
Next, create a tsconfig.json
file and add the following configuration to it:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"allowJs": true,
"removeComments": true,
"resolveJsonModule": true,
"typeRoots": [
"./node_modules/@types"
],
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": [
"esnext"
],
"baseUrl": ".",
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "Node",
"skipLibCheck": true,
},
"include": [
"src/**/*"
],
"exclude": ["node_modules"],
}
Now with our TypeScript environment configured, we can now install the dependencies we need to use the esbuild, for the build and development process (with live reloading).
npm install -D nodemon esbuild esbuild-node-tsc
With these dependencies installed we can configure nodemon.json
:
{
"watch": ["src"],
"ignore": ["src/**/*.test.ts", "node_modules"],
"ext": "ts,mjs,js,json,graphql",
"exec": "etsc && node ./dist/server.js",
"legacyWatch": true
}
Now in our package.json
we are going to specify that we are going to use ESM and we are going to add the following scripts:
{
// ...
"main": "server.js",
"scripts": {
"dev": "nodemon",
"build": "etsc",
"start": "node dist/server.js"
},
// ...
}
Whenever nodemon sees a change in our source code, as soon as there is one, it builds the folder and then reloads the api. However, the code being executed is not TypeScript but the JavaScript code that will be saved in the dist
folder.
Finally, we can create a simple api:
// @/src/server.ts
import fastify, {
FastifyRequest,
FastifyReply,
FastifyInstance,
} from "fastify";
const startServer = async (): Promise<FastifyInstance> => {
const app = fastify();
app.get("/", async (request: FastifyRequest, reply: FastifyReply): Promise<FastifyReply> => {
return reply.send({ hello: "world" });
});
return app;
};
startServer()
.then((app) => app.listen(3333))
.catch(console.error);
Creating an api in Node using TypeScript along with the esbuild is as simple as this, literally. One thing I want to mention, but I think you've noticed this, esbuild-node-tsc
takes into account the tsconfig.json
configuration but the build is done with esbuild.
If you want to try it out without having to configure all this (although it wasn't much), you can clone this repository. Have a nice day 👊
Top comments (4)
Nice post. It helped me a lot in order to configure a new project using esbuild.
I would like to provide an additional point. In my case, I usually work with path aliases in TypeScript, so in order to allow nodemon to understand those paths, it's needed to install the next development dependency:
npm install -D tsconfig-paths
Once it's done, we must update the nodemon configuration file this way:
That's all.
Just wanted to say I've come back and referenced this article several times since I first read it. Great work!
When trying to run the transpiled code I'm getting the following error:
Can I (or should I) change the output files to be .cjs? If yes, how should I do that?
ESBuild is fast! Cool read! 👌