Next.js + Typescript: mejora la manera en que importas componentes y módulos locales
Tags: nextjs, typescript, tips, react
Published: 2020-02-20 17:52:15

Un sinónimo de buena estructuración en un proyecto con Reactjs o Next.js a menudo es dividir los componentes y módulos en entidades más pequeñas para su efectiva reutilización y organización, haciendo así que sean más fáciles de mantener y escalar.

Esto trae un consecuencia que, en lo personal, pienso que hace el código menos legible, confuso y suele ser frustrante: importar módulos o componentes organizados en otros directorios.

Es muy probable que tengas en al menos un componente o módulo de TypeScript algo como esto:

```typescript
import MyComponent from '../../../../../components/myComponent'
import { helperOne, helperTwo } from '../../../../../helpers'
```
En primera instancia, quizá no lo veas tan mal, pero honestamente, ¿podría deducirse de manera rápida dónde están ubicados estos módulos importados? y más allá: cuando debes importar un modulo ¿debes ir saltando entre directorios hasta llegar al que necesitas?

Propongo algo mejor: **absolute imports de TypeScript**.

Con esto, podemos pasar del ejemplo anterior al esto:

```typescript
import MyComponent from '@components/myComponent'
import { helperOne, helperTwo } from '@helpers'
```

Lo cual mejora un montón la experiencia de desarrollo.

# Comenzando

Lo primero es inicializar y/o configurar el proyecto con Next.js y TypeScript. Para ello se creará un proyecto nuevo (en caso de no tenerlo ya) ejecutando los siguientes comandos y siguiendo los pasos:

```bash

# Con YARN
yarn create next-app

# Con NPM
npm init next-app

```

Esto configurará todo lo necesario para el proyecto, sin embargo, para agregar el soporte para TypeScript, se necesitan unos pasos adicionales, tal y como lo mencionan en su [documentación oficial](https://nextjs.org/docs/basic-features/typescript).

Lo primero es ingresar al directorio raíz del proyecto y crear el archivo `tsconfig.json` vacío:

```bash
touch tsconfig.json
```

Una vez creado este archivo, deben instalarse algunas dependencias adicionales necesarias:

```bash
# Con Yarn
yarn add --dev typescript @types/react @types/node

# Con NPM
npm i --dev typescript @types/react @types/node
```

Se cambian las extensiones de archivo `.js` a `.tsx`/`.ts` y finalmente se ejecuta el comando `npm run dev`.

Esto agregará la configuración necesaria al archivo `tsconfig.json` y todo lo demás (como el archivo `next-env.d.ts`) de manera automática.

# Configuración de TypeScript

Ahora bien, para comenzar con nuestra configuración, necesitamos agregar la siguiente configuración al archivo `tsconfig.json`:

```js
// archivo tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".", // Aquí
    "paths": { // Aquí
      "@helpers/*": ["helpers/*"],
      "@components/*": ["components/*"],
      ... 
    },
    ...
  },
  ...
}
```
La explicación de configuración les bastante simple e intuitiva:
- `baseUrl`: Directorio base para resolver nombres de módulos no relativos.
- `paths`: Lista de entradas de asignación de ruta para nombres de módulos a ubicaciones relativas a la `baseUrl`

Luego de hacer esto editores de texto como VS-Code automáticamente reconocerían los *alias* configurados bajo la key `compilerOptions.paths` en el archivo `tsconfig.json`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qwfy8rkqth5rwzybon0g.gif)

Sin embargo, si intentamos compilar el código, arrojará el siguiente error:

```
[ error ] ./pages/api/index.ts
Module not found: Can't resolve '@helpers/router' ...
```

Esto debido a que `WebPack` no reconoce estas rutas al momento de compilar y empaquetar el código, así que es el siguiente paso.

# Configuración de WebPack

Para acceder a la configuración de WebPack en NextJs, debe hacerse desde el archivo de configuración de Next.js `next.config.js`, para este caso especifico, hay una vía fácil: instalar el [plugin](https://github.com/dividab/tsconfig-paths-webpack-plugin) `tsconfig-paths-webpack-plugin`:

```bash
# Con Yarn
yarn add --dev tsconfig-paths-webpack-plugin

# Con NPM
npm install --save-dev tsconfig-paths-webpack-plugin
```

Y para configurarlo:

```js
// archivo next.config.js
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");

module.exports = {
  webpack: config => {
    if (!config.resolve.plugins) {
      config.resolve.plugins = [];
    }

    config.resolve.plugins.push(new TsconfigPathsPlugin());

    return config;
  },
  ...
};

```

<sub>Para saber más sobre cómo acceder a la configuración de WebPack desde Next.Js puedes hacerlo desde [aquí](https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config).</sub>

Con esto ya debería funcionar todo *like a charm*.

Espero les sirva y mejoren sus `imports` y sean coders más felices. Cualquier duda, opinión o critica es bien recibida en los comentarios.

*Easy code, easy life ~*