La evolución del Assets Pipeline a través del tiempo

Y vos quién sos?

  • Ariel Juodziukynas
  • Dev fullstack, principalmente Rails y React
  • Primer contacto con Rails en 2011

Qué son los assets?

  • Archivos estáticos: imágenes, css, js, tipografías, videos, archivos de texto, binarios, etc
  • Archivos CSS y JS cambian seguido
  • Imágenes cambian pero no tanto
  • Videos y tipografías no cambian mucho

Antes de Rails 3.1

Antes de 2011

Todos los assets en /public o con CDNs

Problemas con esto:

  • Caching e invalidación del caché (agregar el querystring "?timestamp" en la url)
  • Un archivo grande vs muchos archivos chicos
  • Sin soporte para otros lenguajes como CoffeeScript -2009- o SASS (TypeScript no existía todavía)
  • Tamaño de archivo no optimizado
  • Difícil reutilizar código de otros lugares

El Assets Pipeline

Con Sprockets - Desde 2011

  • Presentado en Rails 3.1 con la gema `sprockets` como dependencia de Rails
  • En Rails 4.0, la integración entre Sprockets y Rails fue extraida como una nueva dependencia de Rails: `sprockets-rails`
  • Assets en /public siguen siendo válidos

Problemas resueltos:

  • Caché: sprockets agrega un digest/huella al final del nombre del archivos
  • Bundling: reemplaza directivas "require" por el código referenciado (muchos archivos convertidos en uno grande)
  • Transpilación: soporte de CoffeeScript y SASS/SCSS por defecto
  • Tamaño optimizado: usa compresión y ofuscación (uglifiers/minifiers) para remover lo que el navegador no necesita
  • Fácil agregar assets externos usando gemas
  • La gema `jquery-rails` se incluye por defecto

Turbolinks (2013)

  • Incluido por defecto en nuevas aplicaciones desde Rails 4.0
  • Intenta generar una sensación similar a una single-page-app usando multiples páginas
  • La funcionalidad básica funcionaba bien, pero generó muchos problemas durante años al usar paquetes de terceros

Antes de Rails 5.1

Antes de 2016

  • El mundo JS seguía cambiando, y Sprockets agregaba mas funciones para ser compatible
  • Se agregó soporte para importar assets desde node_modules using Yarn
  • Se agregó soporte para nuevos features de ECMAScript (soporte experimental)
  • Otros ecosistemas desarrollaron otra soluciones para el mismo problema
  • Eventualmente, Webpack (2012) ganó la batalla

Webpacker

  • Webpack se volvió una opción para manejar los assets de JS a través de la gema `webpacker` usando el flag `--webpacker` en Rails 5.1
  • La dependencia de `jquery-rails` fue removida a favor del paquete `rails-ujs` incluido en Rails
  • `rails-ujs` estaba escrito en CoffeeScript, por lo que la gema `coffee-rails` era necesaria para usar ese feature de Rails

La Edad Oscura

2019 - 2021

  • El ecosistema JS estaba cambiando más rápido de lo que Sprockets se actualizaba (estándares, patrones, lenguajes, etc)
  • Webpack tenía soporte para todo lo nuevo, por lo que decidieron hacer de Webpacker el bundler por defecto para assets JS en Rails 6.0
  • El resto de tipos de assets se seguía manejando con Sprockets-rails por defecto
  • Era posible usar Webpacker para todos los tipos de assets

Algunos problemas:

  • Webpack no puede leer assets de gemas
  • Las gemas que incluian assets tenías que proveer también un paquete de NPM
  • La migración no era simpre fácil, muchas apps terminaban usando ambos sprockets y webpacker para manejar js y css
  • Multiples formas de usar un recurso externo (por ejemplo: bootstrap necesitaba la gema para helpers, el CSS era manejado con Sprockets y el JS con Webpack)

El presente

Desde 2021 (Rails 7.0)

  • Se anunción que Webpacker era retirado, ya no es default
  • importmap-rails, por defecto desde Rails 7.0 (pero con soporte desde Rails 6)
  • jsbundling-rails, permite usar Webpack y otros bundlers de JS populares: esbuild, rollup, and bun
  • cssbundling-rails, permite usar otros bundlers de CSS populares: tailwind, bulma, dart-sass, etc
  • vite_rails, permite usar Vite (no oficial)
  • Shakapacker, continuación de Webpacker (no oficial)
  • `sprockets-rails` ya no es dependencia
  • `turbolinks` y `rails-ujs` reeplazados por `turbo-rails`
  • Con los nuevos defaults, una app Rails 7.0 nueva ya no depende de Node

El futuro

  • Propshaft por defecto en Rails 8. Funciones muy básicas comparado con Sprockets
  • Sprockets sigue con soporte ("for a long time" según el readme de Propshaft)
  • Features nativas de navegadores:
    • CSS vs SASS
    • JSDoc vs TypeScript
  • React compiler?

Resumen JS

3.0 3.1 3.2 4.0 4.1 4.2 5.0 5.1 5.2 6.0 6.1 7.0 7.x 8-> /public sprockets-rails webpacker shakapacker importmap-rails jsbundling-rails
Opción soportada Opción por defecto

Resumen CSS

3.0 3.1 3.2 4.0 4.1 4.2 5.0 5.1 5.2 6.0 6.1 7.0 7.x 8-> /public sprockets-rails webpacker shakapacker cssbundling-rails propshaft
Opción soportada Opción por defecto
https://arielj.github.io/assets-pipeline-history
Slides

Preguntas?

Recursos:

Dejanos tus comentarios

https://docs.google.com/forms/d/e/1FAIpQLScD-7GXHOB1BkAJLBWmWzQfwX0ABiTYzySqYxvsC4saVLBnMA/viewform