Configurando Alias en webpack + visual code + typescript + jest


Introducción

Este post está basado en este excelente Gist de Carlos Hidalgo

Cuando trabajamos con imports, una de las cosas que más duelen (y huelen) es trabajar con rutas relativas, es decir, si tenemos una estructura como esta:

Ejemplo de estructura de carpetas de proyecto

Ejemplo de estructura de carpetas de proyecto


Y por ejemplos estamos editando el fichero pods/movies/movies-grid.container.ts Y queremos desde nuestra página referenciar a un elemento de la carpeta api, tendríamos que hacer un import del tipo:

import {fetchMovies} from '../../api';

Con uno o dos niveles “../” igual esto no tiene mala pinta, pero a veces te puedes encontrar con cosas como:

import { TrainingSummary } from '../../../../model/trainingSummary';

Y lo que es peor, si refactorizamos y movemos de carpetas ficheros acabamos teniendo un lio de imports.

¿ Que solución podemos aplicar? crear unos alias a nivel de carpeta principal, que nos permitan minimizar el uso de carpetas relativas, es decir en este caso si hago un alias a la carpeta api, el import relativo que creamos anteriormente se quedaría de la siguiente manera:

import {fetchMovies} from '/api';

La idea aquí es crear unos alias en carpetas de primer nivel y evitar el infierno de rutas relativas.

Y..¿ Esto es fácil de configurar? Bueno más que fácil, tiene truco, tienes que saber bien donde tocar:

  • Hay que indicarle a webpack los mappings de esos alias (tocaremos el webpack.config.js).

  • Hay que ayudar a VSCode y Typescript a mapear esos alias (tocaremos el tsconfig.json).

  • Y si tenemos pruebas unitarias con JEST también debemos de indicarle los mapeos de carpeta a alias (aquí actualizaremos el fichero de configuración de jest, sea el jest.json o el propio package.json, depende de donde tengamos la configuración).

Con la hoja de ruta que os vamos a definir, a partir de ahora configurar un grupo de alias va a ser pan comido :).

Configurando webpack

Webpack necesita saber a paths físicos mapean los alias, abrimos el fichero webpack.config.js y añadimos a la sección resolve, una subsección que llamaremos alias y ahí listamos todos los mapeos de alias a ruta, quedaría tal que así:

webpack.config.json

module.exports = {
  resolve: {
    alias: {
      api: path.resolve(__dirname, './src/api/'),
      commonApp: path.resolve(__dirname, './src/common-app/'),
      core: path.resolve(__dirname, './src/core/'),
      layout: path.resolve(__dirname, './src/layout/'),
      pods: path.resolve(__dirname, './src/pods/'),      
      scenes: path.resolve(__dirname, './src/scenes/'),
    },
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  },
La lista de alias es la que usamos en nuestra aplicación, en tu aplicación tendrás otras carpetas y otros alias que podrás configurar según tus necesidades.

Configurando Typescript + Visual Studio code

Ahora nos toca que Typescript y Visual Studio Code se lleven bien con estos alias, para ellos en el tsconfig, tenemos que decirle cual es nuestra carpeta de partida (en este caso la src) y crear una sección de paths en la que añadimos nuestra lista de alias (muy importante: esta lista de paths tiene que ir debajo de la sección de compilerOptions).

tsconfig.json

{
  "compilerOptions": { 
    "moduleResolution": "node",
    "baseUrl": "./src/",
    "paths": {
      "api": ["./src/api/*"],
      "common-app": ["./src/common-app/*"],
      "core": ["./src/core/*"],
      "layout": ["./src/layout/*"],
      "pods": ["./src/pods/*"],
      "scenes": ["./src/scenes/*"]
    }
  }
}

Configurando Jest


Cómo último paso, si estamos usando Jest, tenemos que añadir la lista de paths al fichero de configuración, dependiendo del proyecto la configuracíon de jest te la puedes encontrar en el mismo package.json o en un fichero específico (jest.json o similar), en el ejemplo que cubrimos se encuentra en el jest.json.

/config/jest.json

{
  "moduleNameMapper": {
    "^api/(.*)$": "/src/api/$1",
    "^common-app/(.*)$": "/src/common-app/$1",
    "^core/(.*)$": "/src/core/$1",
    "^layout/(.*)$": "/src/layout/$1",
    "^pods/(.*)$": "/src/pods/$1",
    "^scenes/(.*)$": "/src/scenes/$1"
  }
}

Ejemplo real

Si quieres ver esto aplicado en un proyecto real, aquí tienes:

Agradecimientos

Este post está basado en este excelente Gist de Carlos Hidalgo, que se pego unas horas de investigación y cabezazos hasta que dio con los pasos exactos :).

¿Con ganas de aprender desarrollo Front End?

Si tienes ganas de ponerte al día en el mundo del Front End, impartimos un máster online con clases en vivo. Para más información: http://lemoncode.net/master-frontend