March 2025
Recientemente estoy trabajando con repositorios con multiples lenguajes and sistemas de compilación. Para ser más especificos iOS/Android/Rust/Node/React Native/Flutter. Trabajar con diferentes y multiples sistemas, trae mucha complejidad, especialmente cuando uno trabaja en equipo, cuando todos necesitan correr los mismos comandos para construir, correr lost tests, lints y tener las versiones correctas instaladas.
Cada lenguaje y ecosistema tiene su propia forma de hacer las cosas. Algunos de los patrones que he visto son:
make
, rake
, ninja
, etc.Es un salvaje oeste. Todas estos approachs funcionan pero necesitan mucho cuidado para que funcionen bien. Quería algo sencillo, fácil de leer y de escribir. Preferiblemente en un lenguaje y ecosistema que conozca bien. JavaScript se ajusta bien a todos estos requerimientos, el problema es tener las versiones correctas instaladas en las maquinas de los miembros del equipo, sin embargo, encontre un par de herramientas que solucionan el primer problema, con unos cuantos comandos.
Soy un gran fan de los tool managers. El viaje empezo con asdf
y ahora estoy usando mise
. mise
es un tool manager que permite instalar todo tipo de herramientas con un solo archivo. Hay que pensar que es un package manager pero para todo incluido como lenguajes, sdks, runtime,s, etc. Basicamente permite tener un solo archive mise.toml
que define todas las herramientas necesarias para un proyecto.
Podemos definir la versión exacta de bun/node que el proyecto requiere, sin la necesidad de seguir diferentes pasos de instalación. No hay necesidar de instalar node, después nvm, después Rust, etc.
El Bun Shell es un objecto integrado en bun que permite correr commandos de la terminal dentro de archivos TypeScript. La belleza de este approach es la fácilidad de usar TypeScript para manipular, re-enviar, usar loops, etc. Permitiendo escapar de lo bobo de bash.
Para este proyecto mi mise.toml
parece algo así:
[tools]
node = "14.18.1"
bun = "0.1.0"
rust = "1.58.0"
[hooks]
postinstall = "bun install"
[tasks]
build = "bun zx scripts/build.mts"
Luego existe un script/build.mts
que se ve así:
import { $ } from "bun";
// You can do more things here, like parse the arguments, import other files, etc
await $`cargo build --release`;
await $`flutter build ios`;
En el README del repositorio tengo los siguiente commandos:
brew install mise
mise settings experimental=true
, Necesario para habilitar los hooks, que son experimentales por ahora.mise install
mise build
Finalmente, compila el proyecto. En mi versión final, incluye parametros por ejemplo: mise build ios debug
para compilar la versión para iOS en modo DebugDe esta manera ya no hay más conflictos de versiones, instalaciones incorrectas y todos los comandos siguen un solo patrón.