Rails 5.1 y más allá - Parte 1: Yarn en Rails

Rails 5.1 y más allá - Parte 1: Yarn en Rails

Explorando la integración de Yarn en Rails 5.1, el gestor de paquetes JavaScript que es rápido, seguro y confiable. Aprende cómo Rails abraza el ecosistema JavaScript moderno.

Gerardo Ortega

Hace apenas una semana se anunció la versión más reciente de Ruby on Rails, uno de mis frameworks web favoritos que he usado en muchos proyectos durante más de tres años. Hay muchas características increíbles y nuevos cambios, uno de mis favoritos es la integración con Yarn, una gran herramienta de gestión de paquetes para JavaScript, que es rápida, segura y confiable.

Estoy preparando una serie de posts para explicar los principales cambios introducidos en Rails 5.1. En este post, voy a abordar la nueva forma de manejar JavaScript usando Yarn, y por supuesto voy a escribir un poco sobre Yarn en general. Así que comencemos.

Rails 5.1, la prueba de la madurez del ecosistema

Rails 5.1 resuelve muchos de los “temas pendientes” de los últimos años. Sobre todo, temas relacionados con la gestión de assets que desde la versión 4.0 eran manejados por Sprockets, una gema que nos permitía centralizar todo el proceso de agrupar, usar y compilar todos nuestros assets usando convenciones prácticas.

Aunque Sprockets hace un trabajo fantástico para la mayoría de los desarrolladores, planteó algunos problemas para otros, sobre todo cuando necesitabas trabajar con bibliotecas complejas de terceros en JavaScript, generalmente con muchas dependencias adicionales. Para esos casos, el mantenimiento de bibliotecas de terceros también era un problema a tal grado que generalmente necesitabas instalar gemas adicionales que encapsulaban todo el proceso de integración y facilitaban la actualización a versiones más nuevas de las bibliotecas.

Por otro lado, hace muchos años surgió un conjunto creciente de herramientas de la comunidad JavaScript para resolver muchos de los problemas que los desarrolladores tenían que enfrentar cada vez que comenzaban un nuevo proyecto JavaScript, dando soluciones prácticas a la pregunta: ¿Cómo manejar paquetes y sus dependencias de manera rápida y eficiente? Y así es como surgieron muchas herramientas (como NPM, Bower, Grunt, etc.). Y a veces el proceso de gestionar dependencias de assets en Rails se sentía repetitivo considerando los notables avances en el ecosistema JS para esta área.

No fue una sorpresa que cuando Chris McCord lanzó Phoenix Framework hace dos años, decidiera incluir Brunch como herramienta de construcción de assets, adoptando NPM como gestor de paquetes. Pero, la comunidad Rails mostrando su disposición a adoptar nuevas formas de hacer las cosas si es necesario, decidió con el lanzamiento de Rails 5.1 incluir Yarn como gestor de paquetes y dependencias para assets JS y opcionalmente Webpack para manejar bundles de módulos y compilación. Ese es un gran paso en la dirección correcta hacia donde se dirige el desarrollo web.

En este post cubriremos cómo funciona la integración con Yarn.

Introduciendo Yarn

Yarn es un gestor de paquetes creado por Facebook, y anunciado el año pasado. Según Facebook, estaban usando NPM pero a medida que el tamaño de su base de código y el número de ingenieros trabajando en sus proyectos crecía, se encontraron con problemas de consistencia, seguridad y rendimiento. Así que necesitaban una herramienta que fuera rápida y confiable.

Y lo mejor de todo es que el desarrollo de Yarn está respaldado por otras compañías como Google y Tilde.

Instalando Yarn

macOS

  • Usando Homebrew
brew install yarn
  • Usando MacPorts
sudo port install yarn

Windows

La forma más fácil es usar el instalador, puedes encontrarlo aquí.

También puedes usar Chocolatey

choco install yarn

Y Scoop también

scoop install yarn

Ubuntu

Primero necesitas configurar el repositorio

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

Y finalmente simplemente:

sudo apt-get update && sudo apt-get install yarn

Para verificar que todo salió bien, solo verifica la versión de yarn instalada:

yarn --version

Usando yarn

Ahora, y previo a introducir Yarn aplicado al contexto de RoR, vamos a comenzar a usar Yarn de forma independiente.

Entonces, comencemos un nuevo proyecto usando Yarn:

mkdir yarn_test
cd yarn_test

yarn init

Yarn te preguntará información básica sobre el proyecto, como el nombre del proyecto, versión, descripción, autor, url del repositorio, etc.

Cuando la inicialización haya terminado, verás un nuevo archivo llamado package.json, que contiene los datos que proporcionaste antes.

Y ahora vamos a proceder a agregar nuevas dependencias. Tienes diferentes formas de agregar una dependencia: solo usando su nombre, o especificando su versión o etiqueta. En este caso, solo voy a agregar un paquete react.js sin especificar la versión, para obtener la última.

yarn add react

Y eso es todo. Si revisas el archivo package.json encontrarás la última versión de reactjs.

Opcionalmente puedes agregar diferentes categorías de dependencias, y actualizarlas o eliminarlas. Para instalar todas las dependencias de un proyecto solo necesitas ejecutar

yarn

o

yarn install

Puedes verificar todo el árbol de dependencias en un nuevo archivo que se crea después de instalar el primer paquete, llamado yarn.lock

Y, como no quiero dejar este ejemplo incompleto, creemos una aplicación hello world con react, de la manera fácil.

Primero instalemos el paquete create-react-app, pero globalmente para usarlo desde la terminal.

yarn global add create-react-app

Y ahora, podemos verificar que create-react-app está funcionando pidiendo su versión:

create-react-app --version

Si todo está bien, procedamos a crear nuestra primera aplicación react.js:

create-react-app hello-world

Entonces, verás una salida similar a la siguiente:

Success! Created hello_world at /Users/gerardo/opensource/yarntest/hello_world
Inside that directory, you can run several commands:

yarn start
Starts the development server.

yarn run build
Bundles the app into static files for production.

yarn test
Starts the test runner.

yarn run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can't go back!

We suggest that you begin by typing:

cd hello_world
yarn start

Happy hacking!

¡Increíble! Entonces, probemos nuestra aplicación recién creada:

cd hello_world
yarn start

/////
Compiled successfully!

The app is running at:

http://localhost:3000/

Note that the development build is not optimized.
To create a production build, use yarn run build.

Entonces, si vas a http://localhost:3000/ verás tu aplicación funcionando.

Ahora, echemos un vistazo a los archivos generados:

ls -l

-rw-r--r-- 1 gerardo staff 80668 May 31 10:10 README.md
drwxr-xr-x 774 gerardo staff 26316 May 31 10:18 node_modules
-rw-r--r-- 1 gerardo staff 374 May 31 10:10 package.json
drwxr-xr-x 4 gerardo staff 136 May 31 10:10 public
drwxr-xr-x 8 gerardo staff 272 May 31 10:10 src
-rw-r--r-- 1 gerardo staff 188529 May 31 10:10 yarn.lock

cat package.json

{
  "name": "hello_world",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^15.5.4",
    "react-dom": "^15.5.4"
  },
  "devDependencies": {
    "react-scripts": "0.9.x"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

Si has probado anteriormente otros gestores de paquetes y dependencias, apreciarás lo limpio y fácil que fue llegar a este punto. No voy a profundizar más en reactjs, tal vez en un futuro post voy a abordar eso usando Yarn, pero eso fue una muestra de Yarn. Estoy muy contento de que decidieran integrarlo en el flujo de trabajo de Rails, puedes ver los detalles en este pull request.

Yarn en Rails

Ahora intentemos usar Yarn dentro de una nueva aplicación Rails 5.1.

rails new yarn_test

cd yarn_test

Además de los archivos normales que ves cuando se genera un nuevo proyecto rails, encontrarás un archivo package.json, y si echas un vistazo al archivo inicializador de assets, encontrarás la siguiente línea:

# Add additional assets to the asset load path.

# Rails.application.config.assets.paths << Emoji.images_path

# Add Yarn node_modules folder to the asset load path.

Rails.application.config.assets.paths << Rails.root.join('node_modules')

Entonces, Rails incluye automáticamente el directorio node_modules en el pipeline de assets, solo necesitas hacer referencia al nuevo paquete que quieres agregar, por ejemplo, digamos que queremos usar la biblioteca moment.js. Primero necesitamos instalar la biblioteca usando Yarn:

yarn install moment

Podemos ver que package.json fue actualizado

{
  "name": "yarn_test",
  "private": true,
  "dependencies": {
    "moment": "^2.18.1"
  }
}

Y finalmente necesitamos incluir el nuevo paquete en application.js:

//= require moment/moment

Eso es todo por esta primera parte, en la segunda parte de esta serie voy a abordar Webpack y cómo usarlo para compilar y gestionar bundles de JavaScript.

Gerardo Ortega

About Gerardo Ortega

Software craftsman with a focus on scaling, polyglot programmer, coffee enthusiast, and lifelong learner. Passionate about machine learning, data science, and building great products.