Compiling TypeScript to ESNext for Back-End node.js Apps
Tags: javascript, typescript, node
Published: 2020-07-26 15:16:14

Let's keep it short and sweet! 🍬


##Contents
[Node Version](#node-version)
[Set Node To Use Modules](#set-node-to-use-modules)
[TypeScript Compiler Options](#typescript-compiler-options)
[Change Your Imports](#change-your-imports)
[Why Do This?](#why-do-this)
## Node Version

You'll need node version 13 or higher. We'll be using Node Version Manager to handle this.

```
nvm install latest
```
```
nvm ls
```
**Important!** Note the latest version, then use it for the following command:
```
nvm use <version>
```
_Replace `<version>` with the one installed on your machine._

> **Note**: Proceed with caution when using the latest version over the LTS version in production.
> On Windows 10, I recommend downloading [chocolatey](https://chocolatey.org/install), then use chocolatey to install Node Version Manager; commonly referred to as "nvm".
> [Click here](https://github.com/nvm-sh/nvm) for installation on Unix machines.

## Set Node To Use Modules

Add the following line to your `package.json` file.
```json
"type": "module"
```

## TypeScript Compiler Options

`compilerOptions` needs `target`, `module`, and `moduleResolution` options to be changed in your tsconfig.json file.


```json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "node"
  }
}
```
> **Note:** remove the `resolveJsonModule` option if you have set it. If you need to read JSON data, either use `fs.readFileSync` at the start of your program, or utilise the new [promise variant](https://nodejs.org/dist/latest-v14.x/docs/api/fs.html#fs_fs_promises_api); `await fs.readFile`.

## Change Your Imports

For simplicity, here are some rules:
- All your imports must end with a `.js` file extension, even if they end with `.ts` in your source code. _As far as I know, [Visual Studio Code](https://code.visualstudio.com/) will pick up the correct TypeScript file._
- Make sure your compiled JavaScript files and your TypeScript source files are equal in depth from your project's root folder. _For example, if your TypeScript source files are stored in `./src` then your compiled JavaScript files should be stored in `./out`._

**old:**
```js
import { myModule } from './src/modules'
myModule()
```
**new:**
```js
// If myModule is exported as a named function or function variable.
import { myModule } from './src/modules/myModule/index.js'
myModule()
```
*or:*
```js
// If myModule is exported as the default module.
import * as myModule from './src/modules/myModule/index.js'
//@ts-ignore
myModule.default.myModule()
```
>**Note:** Your file doesn't need to be called `index.js`, but the `.js` file extension must be present.

Done!

## Why Do This?
- No more asynchronous generators!
- Aligns your source code closer to your compiled code.
- Easier to debug in production, or where source maps aren't available.
- You can afford to experiment with the latest APIs.
- Reduces dependencies (Babel and CommonJS).
- Performance gains.
- You just need a compiler which removes the types from your TypeScript files.
- You use the debug feature in Visual Studio Code and it already compiles for you.
- Your life depends on it for some unknown reason.