Más en rubyonrails.org: Más Ruby on Rails

NO LEA ESTE ARCHIVO EN GITHUB, LAS GUÍAS SE PUBLICAN EN https://railsguides.es/

Constantes de Autocarga y Recarga (modo clásico)

Esta guía cubre la canalización de activos.

Después de leer esta guía, sabrá:

1 What is the Asset Pipeline?

La canalización de activos proporciona un marco para concatenar y minificar o comprimir Activos de JavaScript y CSS. También agrega la capacidad de escribir estos activos en otros lenguajes y preprocesadores como CoffeeScript, Sass y ERB. Permite que los activos de su aplicación se combinen automáticamente con los activos. de otras gemas.

La canalización de activos es implementada por la gema sprockets-rails y está habilitado de forma predeterminada. Puede deshabilitarlo mientras crea una nueva aplicación al pasando la opción --skip-sprockets.

$ rails new appname --skip-sprockets

Rails agrega automáticamente los sass-rails gem a su Gemfile, que es utilizado por Sprockets para Recopilación de Sass:

gem 'sass-rails'

El uso de la opción --skip-sprockets evitará que Rails agregue esta gema, por lo que si luego desea habilitar la canalización de activos tendrá que agregarlo a su Gemfile manualmente. También, crear una aplicación con la opción --skip-sprockets generará un archivo config/application.rb ligeramente diferente, con una declaración (require) para los Sprockets railtie que se comenta. Tendrás que eliminar el operador de comentarios en esa línea para luego habilitar la canalización de activos:

# require "sprockets/railtie"

Para establecer métodos de compresión de activos, establezca las opciones de configuración adecuadas en production.rb - config.assets.css_compressor para su CSS y config.assets.js_compressor para su JavaScript:

config.assets.css_compressor = :yui
config.assets.js_compressor = :uglifier

La gema sass-rails se usa automáticamente para la compresión CSS si está incluida en el Gemfile y no se establece la opción config.assets.css_compressor.

1.1 Main Features

La primera característica de la tubería es concatenar activos, lo que puede reducir la número de solicitudes que realiza un navegador para representar una página web. Los navegadores web son limitado en el número de solicitudes que pueden realizar en paralelo, por lo que menos las solicitudes pueden significar una carga más rápida para su aplicación.

Sprockets concatena todos los archivos JavaScript en un archivo maestro .js y todos Archivos CSS en un archivo maestro .css. Como aprenderá más adelante en esta guía, Puede personalizar esta estrategia para agrupar archivos de la forma que desee. En producción, Rails inserta una huella digital SHA256 en cada nombre de archivo para que el archivo sea almacenado en caché por el navegador web. Puede invalidar la caché modificando esto huella digital, que ocurre automáticamente cada vez que cambia el contenido del archivo.

La segunda característica de la cartera de activos es la minificación o compresión de activos. Para los archivos CSS, esto se hace eliminando los espacios en blanco y los comentarios. Para JavaScript, Se pueden aplicar procesos más complejos. Puede elegir entre un conjunto de opciones o especifique las suyas propias.

La tercera característica de la canalización de activos es que permite codificar activos a través de un lenguaje de nivel superior, con precompilación hasta los activos reales. Soportado Los lenguajes incluyen Sass para CSS, CoffeeScript para JavaScript y ERB para ambos por defecto.

1.2 What is Fingerprinting and Why Should I Care?

La toma de huellas dactilares es una técnica que hace que el nombre de un archivo dependa de la contenido del archivo. Cuando cambia el contenido del archivo, el nombre del archivo también se cambiado. Para el contenido que es estático o que se cambia con poca frecuencia, esto proporciona una una forma sencilla de saber si dos versiones de un archivo son idénticas, incluso en diferentes servidores o fechas de implementación.

Cuando un nombre de archivo es único y se basa en su contenido, los encabezados HTTP se pueden configurar como Fomentar las cachés en todas partes (ya sea en CDN, ISP, en equipos de red, o en navegadores web) para mantener su propia copia del contenido. Cuando el contenido es actualizado, la huella dactilar cambiará. Esto hará que los clientes remotos solicitar una nueva copia del contenido. Esto se conoce generalmente como cache busting.

La técnica que utiliza Sprockets para la toma de huellas dactilares es insertar un hash del contenido en el nombre, generalmente al final. Por ejemplo, un archivo CSS global.css

global-908e25f4bf641868d8683022a5b62f54.css

Esta es la estrategia adoptada por la cartera de activos de Rails.

La antigua estrategia de Rails era agregar una cadena de consulta basada en fecha a cada activo vinculado con un ayudante incorporado. En la fuente, el código generado se ve así:

/stylesheets/global.css?1309495796

La estrategia de la cadena de consulta tiene varias desventajas:

  1. ** No todos los cachés almacenarán en caché de manera confiable el contenido donde el nombre del archivo solo difiere por parámetros de consulta **

    Steve Souders recomienda, "...avoiding a querystring for cacheable resources". Encontró que en este caso 5-20% de las solicitudes no se almacenarán en caché. Las cadenas de consulta en particular no funciona en absoluto con algunas CDN para la invalidación de caché.

  2. El nombre del archivo puede cambiar entre nodos en entornos de varios servidores.

    La cadena de consulta predeterminada en Rails 2.x se basa en la hora de modificación de Los archivos. Cuando los activos se implementan en un clúster, no hay garantía de que Las marcas de tiempo serán las mismas, lo que resultará en el uso de diferentes valores dependiendo en qué servidor maneja la solicitud.

  3. Demasiada invalidación de caché

    Cuando se implementan activos estáticos con cada nueva versión de código, el mtime (hora de la última modificación) de todos estos archivos cambia, lo que obliga a clientes para recuperarlos de nuevo, incluso cuando el contenido de esos activos no haya cambiado.

La toma de huellas dactilares soluciona estos problemas al evitar las cadenas de consulta y al garantizar que los nombres de los archivos sean coherentes en función de su contenido.

La toma de huellas dactilares está habilitada de forma predeterminada tanto para el desarrollo como para la producción Ambientes. Puede habilitarlo o deshabilitarlo en su configuración a través del Opción config.assets.digest.

Más lectura:

2 How to Use the Asset Pipeline

En versiones anteriores de Rails, todos los activos se ubicaban en subdirectorios de public como images, javascripts y stylesheets. Con el activo pipeline, la ubicación preferida para estos activos es ahora la app/assets directorio. Los archivos de este directorio son servidos por el middleware Sprockets.

Los activos todavía se pueden colocar en la jerarquía "pública". Cualquier activo bajo "público" serán servidos como archivos estáticos por la aplicación o el servidor web cuando config.public_file_server.enabled se establece en verdadero. Deberías usar app/assets para archivos que deben someterse a un procesamiento previo antes de ser entregados.

En producción, Rails precompila estos archivos en public/assets de forma predeterminada. los Las copias precompiladas son luego servidas como activos estáticos por el servidor web. Los archivos en app/assets nunca se sirven directamente en producción.

2.1 Controller Specific Assets

Cuando genera un andamio o un controlador, Rails también genera un Archivo de hoja de estilo en cascada (o archivo SCSS si sass-rails está en elGemfile) para ese controlador. Además, al generar un andamio, Rails genera el archivo scaffolds.css (oscaffolds.scss si sass-rails está en el Gemfile.)

Por ejemplo, si genera un ProjectsController, Rails también agregará un nuevo archivo en app/assets/stylesheets/projects.scss. Por defecto, estos archivos serán listo para ser usado por su aplicación inmediatamente usando la directiva require_tree. Ver Manifest Files and Directives para obtener más detalles. en require_tree.

También puede optar por incluir hojas de estilo específicas del controlador y archivos JavaScript solo en sus respectivos controladores utilizando lo siguiente:

<%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag params[:controller] %>

Al hacer esto, asegúrese de no utilizar la directiva require_tree, ya que resultará en que sus activos se incluyan más de una vez.

ADVERTENCIA: cuando utilice la precompilación de activos, deberá asegurarse de que su Los activos del controlador se precompilarán al cargarlos por página. Por Los archivos predeterminados .coffee y .scss no serán precompilados por sí mismos. Ver Precompiling Assets para obtener más información sobre cómo trabajos de precompilación.

Debe tener un tiempo de ejecución compatible con ExecJS para poder utilizar CoffeeScript. Si está utilizando macOS o Windows, tiene un tiempo de ejecución de JavaScript instalado en su sistema operativo. Consulte la documentación de ExecJS para conocer todos los tiempos de ejecución de JavaScript admitidos.

También puede deshabilitar la generación de archivos de activos específicos del controlador agregando el siguiendo a su configuración config/application.rb:

  config.generators do |g|
    g.assets false
  end

2.2 Asset Organization

Los activos de canalización se pueden colocar dentro de una aplicación en una de estas tres ubicaciones: app/assets, lib/assets o vendor/assets.

  • app/assets es para activos que son propiedad de la aplicación, como personalizados imágenes, archivos JavaScript u hojas de estilo.

  • lib/assets es para el código de sus propias bibliotecas que realmente no encaja en el alcance de la aplicación o las bibliotecas que se comparten entre aplicaciones.

  • vendor/assets es para activos que son propiedad de entidades externas, como código para complementos de JavaScript y marcos CSS. Tenga en cuenta que un tercero código con referencias a otros archivos también procesados ​​por el activo Pipeline (imágenes, hojas de estilo, etc.), deberán reescribirse para usar ayudantes como asset_path.

2.2.1 Search Paths

Cuando se hace referencia a un archivo desde un manifiesto o un ayudante, Sprockets busca en el tres ubicaciones de activos predeterminadas para ello.

Las ubicaciones predeterminadas son: las images, javascripts and stylesheets directorios en la carpeta app/assets, pero estos subdirectorios no son especiales - se buscará cualquier ruta bajo assets/*.

Por ejemplo, estos archivos:

app/assets/javascripts/home.js
lib/assets/javascripts/moovinator.js
vendor/assets/javascripts/slider.js
vendor/assets/somepackage/phonebox.js

sería referenciado en un manifiesto como este:

//= require home
//= require moovinator
//= require slider
//= require phonebox

También se puede acceder a los activos dentro de los subdirectorios.

app/assets/javascripts/sub/something.js

se hace referencia como: js //= require sub/something

Puede ver la ruta de búsqueda inspeccionando Rails.application.config.assets.paths en la consola de Rails.

Además de las rutas estándar assets/*, se pueden crear rutas adicionales (totalmente calificadas). agregado a la canalización en config/initializers/assets.rb. Por ejemplo:

Rails.application.config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")

Las rutas se recorren en el orden en que aparecen en la ruta de búsqueda. Por defecto, esto significa que los archivos en app/assets tienen prioridad y se enmascararán rutas correspondientes en lib y vendor.

Es importante tener en cuenta que los archivos a los que desea hacer referencia fuera de un manifiesto deben se agregarán a la matriz de precompilación o no estarán disponibles en la producción ambiente.

2.2.2 Using Index Files

Sprockets usa archivos llamados index (con las extensiones relevantes) para un especial propósito.

Por ejemplo, si tiene una biblioteca jQuery con muchos módulos, que se almacena en lib/assets/javascripts/library_name, el archivo lib/assets/javascripts/library_name/index.js sirve como el manifiesto de todos los archivos de esta biblioteca. Este archivo podría incluir una lista de todos los archivos requeridos en orden, o una simple directiva require_tree.

Se puede acceder a la biblioteca en su conjunto en el manifiesto de la aplicación así:

//= require library_name

Esto simplifica el mantenimiento y mantiene las cosas limpias al permitir que el código relacionado agruparse antes de su inclusión en otro lugar.

Sprockets no agrega ningún método nuevo para acceder a sus activos; aún usa el familiar javascript_include_tag ystylesheet_link_tag:

<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>

Si usa la gema turbolinks, que se incluye por defecto en Rails, entonces incluir la opción 'data-turbolinks-track' que hace que turbolinks compruebe si un activo se ha actualizado y, si es así, lo carga en la página:

<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "reload" %>
<%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %>

En vistas normales, puede acceder a imágenes en el directorio app/assets/images Me gusta esto:

<%= image_tag "rails.png" %>

Siempre que la canalización esté habilitada dentro de su aplicación (y no deshabilitada en el contexto del entorno actual), este archivo es servido por Sprockets. Si un archivo existe en public/assets/rails.png y es servido por el servidor web.

Alternativamente, una solicitud de un archivo con un hash SHA256 como public/assets/rails-f90d8a84c707a8dc923fca1ca1895ae8ed0a09237f6992015fef1e11be77c023.png se trata de la misma manera. La forma en que se generan estos hashes se trata en el En Producción más adelante en esta guía.

Sprockets también buscará a través de las rutas especificadas en config.assets.paths, que incluye las rutas de aplicación estándar y cualquier ruta agregada por Rails motores.

Las imágenes también se pueden organizar en subdirectorios si es necesario, y luego se accede especificando el nombre del directorio en la etiqueta:

<%= image_tag "icons/rails.png" %>

si está compilando previamente sus activos (consulte En producción a continuación), la vinculación a un activo que no existe generará una excepción en el página de llamada. Esto incluye vincular a una cadena en blanco. Como tal, tenga cuidado al usar image_tag y los demás ayudantes con datos proporcionados por el usuario.

2.3.1 CSS and ERB

La cartera de activos evalúa automáticamente ERB. Esto significa que si agrega un extensión erb a ​​un recurso CSS (por ejemplo, application.css.erb), luego ayudantes como asset_path están disponibles en sus reglas CSS:

.class { background-image: url(<%= asset_path 'image.png' %>) }

Esto escribe la ruta al activo particular al que se hace referencia. En este ejemplo, Tendría sentido tener una imagen en una de las rutas de carga de activos, como app/assets/images/image.png, al que se hace referencia aquí. Si esta imagen es ya disponible en public/assets como un archivo de huellas digitales, entonces esa ruta es referenciado.

Si desea utilizar un URI de datos - un método para incrustar los datos de la imagen directamente en el archivo CSS; puede usar el ayudante asset_data_uri.

#logo { background: url(<%= asset_data_uri 'logo.png' %>) }

Esto inserta un URI de datos con el formato correcto en la fuente CSS.

Tenga en cuenta que la etiqueta de cierre no puede ser del estilo -%>.

2.3.2 CSS and Sass

Al utilizar la canalización de activos, las rutas a los activos deben reescribirse y sass-rails proporciona ayudantes-url y -path (con guiones en Sass, subrayado en Ruby) para las siguientes clases de activos: imagen, fuente, video, audio, JavaScript y hoja de estilo.

  • image-url "rails.png") devuelve url(/assets/rails.png)
  • image-path("rails.png") devuelve "/assets/rails.png "

La forma más genérica también se puede utilizar:

  • asset-url("rails.png") devuelve url(/assets/rails.png)
  • asset-path("rails.png") devuelve "/assets/rails.png "
2.3.3 JavaScript/CoffeeScript and ERB

Si agrega una extensión erb a ​​un activo de JavaScript, convirtiéndola en algo como application.js.erb, puede usar el ayudanteasset_path en su Código JavaScript:

$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });

Esto escribe la ruta al activo particular al que se hace referencia.

Del mismo modo, puede utilizar el ayudante asset_path en archivos CoffeeScript conerb extensión (por ejemplo, application.coffee.erb):

$('#logo').attr src: "<%= asset_path('logo.png') %>"

2.4 Manifest Files and Directives

Sprockets usa archivos de manifiesto para determinar qué activos incluir y servir. Estos archivos de manifiesto contienen directives - instrucciones que le dicen a Sprockets qué archivos necesitar para construir un solo archivo CSS o JavaScript. Con estas directivas, Sprockets carga los archivos especificados, los procesa si necesario, los concatena en un solo archivo y luego los comprime (basado en el valor de Rails.application.config.assets.js_compressor). Sirviendo un archivo en lugar de muchos, el tiempo de carga de las páginas se puede reducir considerablemente porque el navegador realiza menos solicitudes. La compresión también reduce el tamaño del archivo, lo que permite el navegador para descargarlos más rápido.

Por ejemplo, con un archivo app/assets/javascripts/application.js que contenga el siguientes líneas:

// ...
//= require rails-ujs
//= require turbolinks
//= require_tree .

En los archivos JavaScript, las directivas Sprockets comienzan con // =. En el caso anterior, el archivo utiliza las directivas require yrequire_tree. El require La directiva se usa para decirle a Sprockets los archivos que desea requerir. Aquí estás requiriendo los archivos rails-ujs.js yturbolinks.js que están disponibles en alguna parte en la ruta de búsqueda de Sprockets. No es necesario que proporcione las extensiones de forma explícita. Sprockets asume que necesita un archivo .js cuando se hace desde dentro de un.js expediente.

La directiva require_tree le dice a Sprockets que incluya de forma recursiva todos Archivos JavaScript en el directorio especificado en la salida. Estos caminos deben ser especificado en relación con el archivo de manifiesto. También puede utilizar el Directiva require_directory que incluye todos los archivos JavaScript solo en el directorio especificado, sin recursividad.

Las directivas se procesan de arriba a abajo, pero el orden en el que se incluido por require_tree no está especificado. No debe confiar en ningún orden entre esos. Si necesita asegurarse de que algún JavaScript en particular termine encima de otro en el archivo concatenado, primero requiere el archivo de requisitos previos en el manifiesto. Tenga en cuenta que la familia de directivas require evita archivos de incluirse dos veces en la salida.

Rails también crea un archivo app/assets / stylesheets / application.css predeterminado que contiene estas líneas:

/* ...
*= require_self
*= require_tree .
*/

Los rieles crean app/assets/stylesheets/application.css independientemente de si el La opción --skip-sprockets se usa al crear una nueva aplicación Rails. Esto es para que pueda agregar fácilmente la canalización de activos más adelante si lo desea.

Las directivas que funcionan en archivos JavaScript también funcionan en hojas de estilo (aunque obviamente incluye hojas de estilo en lugar de archivos JavaScript). los La directiva require_tree en un manifiesto CSS funciona de la misma manera que JavaScript uno, que requiere todas las hojas de estilo del directorio actual.

En este ejemplo, se utiliza require_self. Esto coloca el CSS contenido en el archivo (si lo hay) en la ubicación precisa de la llamada require_self.

NOTA. Si desea usar varios archivos Sass, generalmente debe usar la regla @import rule en lugar de estas directivas Sprockets. Cuando se utilizan directivas Sprockets, los archivos Sass existen dentro su propio alcance, haciendo que las variables o mixins solo estén disponibles dentro del documento en el que se definieron.

También puede hacer un globbing de archivos usando @import "*" y @import "**/*" para agregar el árbol completo, lo que equivale a cómo funciona require_tree. Consulte la documentación de sass-rails para obtener más información y advertencias importantes.

Puede tener tantos archivos de manifiesto como necesite. Por ejemplo, el admin.css y el manifiesto admin.js podría contener los archivos JS y CSS que se utilizan para sección de administración de una aplicación.

Se aplican las mismas observaciones sobre pedidos hechas anteriormente. En particular, puede especificar archivos individuales y se compilan en el orden especificado. Por ejemplo tu podría concatenar tres archivos CSS juntos de esta manera:

/* ...
*= require reset
*= require layout
*= require chrome
*/

2.5 Preprocessing

Las extensiones de archivo utilizadas en un activo determinan qué procesamiento previo se aplica. Cuando se genera un controlador o un andamio con el conjunto de gemas Rails predeterminado, El archivo SCSS se genera en lugar de un archivo CSS normal. El ejemplo usado antes era un controlador llamado "proyectos", que generaba un archivo app/assets/stylesheets/projects.scss.

En el modo de desarrollo, o si la canalización de activos está deshabilitada, cuando este archivo está solicitado es procesado por el procesador proporcionado por la gema sass-rails y luego se envía de vuelta al navegador como CSS. Cuando la canalización de activos está habilitada, El archivo está preprocesado y se coloca en el directorio public/assets para servirlo ya sea la aplicación Rails o el servidor web.

Se pueden solicitar capas adicionales de preprocesamiento agregando otras extensiones, donde cada extensión se procesa de derecha a izquierda. Estos deben ser utilizado en el orden en que se debe aplicar el procesamiento. Por ejemplo, una hoja de estilo llamado app/assets/stylesheets/projects.scss.erb se procesa primero como ERB, luego SCSS, y finalmente sirvió como CSS. Lo mismo se aplica a un archivo JavaScript: app/assets/javascripts/projects.coffee.erb se procesa como ERB, luego CoffeeScript y sirvió como JavaScript.

Tenga en cuenta que el orden de estos preprocesadores es importante. Por ejemplo, si usted llamó a su archivo JavaScript app/assets/javascripts/projects.erb.coffee luego se procesaría primero con el intérprete de CoffeeScript, que no entendería ERB y, por lo tanto, tendría problemas.

3 In Development

En el modo de desarrollo, los activos se sirven como archivos separados en el orden en que se especificado en el archivo de manifiesto.

Este manifiesto app/assets/javascripts/application.js`:

//= require core
//= require projects
//= require tickets

generaría este HTML:

<script src="/assets/core.js?body=1"></script>
<script src="/assets/projects.js?body=1"></script>
<script src="/assets/tickets.js?body=1"></script>

Sprockets requiere el parámetro body.

3.1 Raise an Error When an Asset is Not Found

Si está utilizando sprockets-rails> = 3.2.0 puede configurar lo que sucede cuando se realiza una búsqueda de activos y no se encuentra nada. Si desactiva la "reserva de activos" entonces se generará un error cuando no se pueda encontrar un activo.

config.assets.unknown_asset_fallback = false

Si la "reserva de activos" está habilitada, cuando no se pueda encontrar un activo, la ruta será salida en su lugar y no surgió ningún error. El comportamiento de reserva de activos está deshabilitado de forma predeterminada.

3.2 Turning Digests Off

Puede desactivar los resúmenes actualizando config/environment/development.rb a incluir:

config.assets.digest = false

Cuando esta opción es verdadera, se generarán resúmenes para las URL de los activos.

3.3 Turning Debugging Off

Puede desactivar el modo de depuración actualizando config/environment/development.rb a incluir.

config.assets.debug = false

Cuando el modo de depuración está desactivado, Sprockets concatena y ejecuta los preprocesadores en todos los archivos. Con el modo de depuración desactivado, el manifiesto anterior generar en su lugar:

<script src="/assets/application.js"></script>

Los activos se compilan y almacenan en caché en la primera solicitud después de que se inicia el servidor. Sprockets establece un encabezado HTTP must-revalidate Cache-Control para reducir la solicitud sobrecarga en solicitudes posteriores: en estas, el navegador obtiene un 304 (No modificado) respuesta.

Si alguno de los archivos del manifiesto ha cambiado entre solicitudes, el servidor responde con un nuevo archivo compilado.

El modo de depuración también se puede habilitar en los métodos auxiliares de Rails:

<%= stylesheet_link_tag "application", debug: true %>
<%= javascript_include_tag "application", debug: true %>

La opción :debug es redundante si el modo de depuración ya está activado.

También puede habilitar la compresión en el modo de desarrollo como una verificación de cordura, y deshabilítelo bajo demanda según sea necesario para la depuración.

4 In Production

En el entorno de producción, Sprockets utiliza el esquema de huellas dactilares descrito encima. De forma predeterminada, Rails asume que los activos se han compilado previamente y se servido como activos estáticos por su servidor web.

Durante la fase de precompilación, se genera un SHA256 a partir del contenido del archivos compilados e insertados en los nombres de archivo a medida que se escriben en el disco. Los ayudantes de Rails utilizan estos nombres con huellas digitales en lugar del manifiesto. nombre.

Por ejemplo esto:

<%= javascript_include_tag "application" %>
<%= stylesheet_link_tag "application" %>

generates something like this:

<script src="/assets/application-908e25f4bf641868d8683022a5b62f54.js"></script>
<link href="/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css" media="screen"
rel="stylesheet" />

NOTA: con Asset Pipeline, las opciones :cache y :concat no se utilizan ya, elimine estas opciones de la etiqueta javascript_include_tag y stylesheet_link_tag.

El comportamiento de las huellas digitales está controlado por el config.assets.digest opción de inicialización (que por defecto es "true").

En circunstancias normales, la opción predeterminada config.assets.digest no debe cambiarse. Si no hay resúmenes en los nombres de archivo y el futuro lejano Los encabezados están configurados, los clientes remotos nunca sabrán recuperar los archivos cuando su cambios de contenido.

4.1 Precompiling Assets

Rails viene con un comando para compilar los manifiestos de activos y otros archivos en la tubería.

Los activos compilados se escriben en la ubicación especificada en config.assets.prefix. Por defecto, este es el directorio /assets.

Puede llamar a este comando en el servidor durante la implementación para crear compilado versiones de sus activos directamente en el servidor. Consulte la siguiente sección para información sobre la compilación local.

El comando es:

$ RAILS_ENV=production rails assets:precompile

Esto vincula la carpeta especificada en config.assets.prefix a shared/assets. Si ya usa esta carpeta compartida, deberá escribir su propia implementación mando.

Es importante que esta carpeta se comparta entre implementaciones para que de forma remota Las páginas almacenadas en caché que hacen referencia a los activos compilados antiguos aún funcionan durante la vida de la página en caché.

El comparador predeterminado para compilar archivos incluye application.js, application.css y todos los archivos que no sean JS / CSS (esto incluirá todos los activos de imagen automáticamente) de las carpetas app/assets, incluidas tus gemas:

[ Proc.new { |filename, path| path =~ /app\/assets/ && !%w(.js .css).include?(File.extname(filename)) },
/application.(css|js)$/ ]

El comparador (y otros miembros de la matriz de precompilación; ver más abajo) es aplicado a los nombres de archivos compilados finales. Esto significa cualquier cosa que compile Se excluye JS/CSS, así como los archivos JS/CSS sin procesar; por ejemplo, ".coffee" y Los archivos .scss ** no ** se incluyen automáticamente ya que se compilan en JS / CSS.

Si tiene otros manifiestos u hojas de estilo individuales y archivos JavaScript para include, puede agregarlos a la matriz precompile en config/initializers/assets.rb:

Rails.application.config.assets.precompile += %w( admin.js admin.css )

Especifique siempre un nombre de archivo compilado esperado que termine con .js o .css, incluso si desea agregar archivos Sass o CoffeeScript a la matriz de precompilación.

El comando también genera un .sprockets-manifest-randomhex.json (donde randomhex es una cadena hexadecimal aleatoria de 16 bytes) que contiene una lista con todos sus activos y sus respectivos huellas dactilares. Esto lo utilizan los métodos auxiliares de Rails para evitar mapeo de solicitudes de nuevo a Sprockets. Un archivo de manifiesto típico se ve así:

{"files":{"application-aee4be71f1288037ae78b997df388332edfd246471b533dcedaa8f9fe156442b.js":{"logical_path":"application.js","mtime":"2016-12-23T20:12:03-05:00","size":412383,
"digest":"aee4be71f1288037ae78b997df388332edfd246471b533dcedaa8f9fe156442b","integrity":"sha256-ruS+cfEogDeueLmX3ziDMu39JGRxtTPc7aqPn+FWRCs="},
"application-86a292b5070793c37e2c0e5f39f73bb387644eaeada7f96e6fc040a028b16c18.css":{"logical_path":"application.css","mtime":"2016-12-23T19:12:20-05:00","size":2994,
"digest":"86a292b5070793c37e2c0e5f39f73bb387644eaeada7f96e6fc040a028b16c18","integrity":"sha256-hqKStQcHk8N+LA5fOfc7s4dkTq6tp/lub8BAoCixbBg="},
"favicon-8d2387b8d4d32cecd93fa3900df0e9ff89d01aacd84f50e780c17c9f6b3d0eda.ico":{"logical_path":"favicon.ico","mtime":"2016-12-23T20:11:00-05:00","size":8629,
"digest":"8d2387b8d4d32cecd93fa3900df0e9ff89d01aacd84f50e780c17c9f6b3d0eda","integrity":"sha256-jSOHuNTTLOzZP6OQDfDp/4nQGqzYT1DngMF8n2s9Dto="},
"my_image-f4028156fd7eca03584d5f2fc0470df1e0dbc7369eaae638b2ff033f988ec493.png":{"logical_path":"my_image.png","mtime":"2016-12-23T20:10:54-05:00","size":23414,
"digest":"f4028156fd7eca03584d5f2fc0470df1e0dbc7369eaae638b2ff033f988ec493","integrity":"sha256-9AKBVv1+ygNYTV8vwEcN8eDbxzaequY4sv8DP5iOxJM="}},
"assets":{"application.js":"application-aee4be71f1288037ae78b997df388332edfd246471b533dcedaa8f9fe156442b.js",
"application.css":"application-86a292b5070793c37e2c0e5f39f73bb387644eaeada7f96e6fc040a028b16c18.css",
"favicon.ico":"favicon-8d2387b8d4d32cecd93fa3900df0e9ff89d01aacd84f50e780c17c9f6b3d0eda.ico",
"my_image.png":"my_image-f4028156fd7eca03584d5f2fc0470df1e0dbc7369eaae638b2ff033f988ec493.png"}}

La ubicación predeterminada para el manifiesto es la raíz de la ubicación especificada en config.assets.prefix ('/ assets' por defecto).

Si faltan archivos precompilados en producción, obtendrá un Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError excepción que indica el nombre de los archivos que faltan.

4.1.1 Far-future Expires Header

Los activos precompilados existen en el sistema de archivos y su sitio web los proporciona directamente. servidor. No tienen encabezados de futuro lejano de forma predeterminada, por lo que para obtener el beneficio de huellas digitales, tendrá que actualizar la configuración de su servidor para agregar esos encabezados.

Para Apache:

# The Expires* directives requires the Apache module
# `mod_expires` to be enabled.
<Location /assets/>
  # Use of ETag is discouraged when Last-Modified is present
  Header unset ETag
  FileETag None
  # RFC says only cache for 1 year
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
</Location>

Para NGINX:

location ~ ^/assets/ {
  expires 1y;
  add_header Cache-Control public;

  add_header ETag "";
}

4.2 Local Precompilation

A veces, es posible que no desee o no pueda compilar activos en la producción servidor. Por ejemplo, es posible que tenga acceso de escritura limitado a su producción sistema de archivos, o puede planear implementar con frecuencia sin realizar ningún cambio en sus activos.

En tales casos, puede precompilar activos localmente, es decir, agregar un conjunto de activos compilados y listos para producción en su repositorio de código fuente antes empujando a la producción. De esta manera, no es necesario precompilarlos por separado. en el servidor de producción en cada implementación.

Como arriba, puede realizar este paso usando

$ RAILS_ENV=production rails assets:precompile

Tenga en cuenta las siguientes advertencias:

  • Si los activos precompilados están disponibles, se servirán, incluso si no coinciden con los activos originales (sin compilar), incluso en el desarrollo servidor._

Para garantizar que el servidor de desarrollo siempre compile activos sobre la marcha (y así siempre refleja el estado más reciente del código), el desarrollo entorno _ debe configurarse para mantener los activos precompilados en un entorno diferente ubicación que la producción. De lo contrario, cualquier activo precompilado para su uso en producción aplastará las solicitudes de ellos en el desarrollo (es decir, los cambios que realice en los activos no se reflejarán en el navegador).

Puede hacer esto agregando la siguiente línea a config/environment/development.rb:

  config.assets.prefix = "/dev-assets"
  • La tarea de precompilación de activos en su herramienta de implementación (por ejemplo, Capistrano) debería estar discapacitado.
  • Todos los compresores o minificadores necesarios deben estar disponibles en su desarrollo sistema.

4.3 Live Compilation

En algunas circunstancias, es posible que desee utilizar la compilación en vivo. En este modo todos Las solicitudes de activos en la tubería son manejadas directamente por Sprockets.

Para habilitar este conjunto de opciones:

config.assets.compile = true

En la primera solicitud, los activos se compilan y almacenan en caché como se describe en Activos Cache Store y los nombres de manifiesto utilizados en los ayudantes. se modifican para incluir el hash SHA256.

Sprockets también establece el encabezado HTTP Cache-Control en max-age=31536000. Esta señala todos los cachés entre su servidor y el navegador del cliente que este contenido (el archivo servido) se puede almacenar en caché durante 1 año. El efecto de esto es reducir la número de solicitudes de este activo desde su servidor; el activo tiene buenas posibilidades de estar en el caché del navegador local o en algún caché intermedio.

Este modo usa más memoria, funciona peor que el predeterminado y no recomendado.

Si está implementando una aplicación de producción en un sistema sin ningún tiempos de ejecución de JavaScript preexistentes, es posible que desee agregar uno a su Gemfile:

group :production do
  gem 'mini_racer'
end

4.4 CDNs

CDN son las siglas de Content Delivery Network, son diseñado principalmente para almacenar en caché activos en todo el mundo para que cuando un navegador solicita el activo, una copia en caché estará geográficamente cerca de ese navegador. Si está sirviendo activos directamente desde su servidor Rails en producción, el La mejor práctica es utilizar un CDN delante de su aplicación.

Un patrón común para usar una CDN es configurar su aplicación de producción como el servidor "origen". Esto significa que cuando un navegador solicita un activo de la CDN y hay una falta de caché, tomará el archivo de su servidor sobre la marcha y luego almacenarlo en caché. Por ejemplo, si está ejecutando una aplicación Rails en example.com y tener un CDN configurado en mycdnsubdomain.fictional-cdn.com, luego, cuando se realiza una solicitud a mycdnsubdomain.fictional- cdn.com/assets/smile.png, el CDN consultará su servidor una vez en example.com/assets/smile.png y almacenar en caché la solicitud. La siguiente solicitud al La CDN que ingresa a la misma URL llegará a la copia en caché. Cuando el CDN puede sirva un activo directamente, la solicitud nunca toca su servidor Rails. Desde el los activos de una CDN están geográficamente más cerca del navegador, la solicitud es más rápido, y dado que su servidor no necesita perder tiempo sirviendo activos, puede céntrese en servir el código de la aplicación lo más rápido posible.

4.4.1 Set up a CDN to Serve Static Assets

Para configurar su CDN, debe tener su aplicación ejecutándose en producción en Internet en una URL disponible públicamente, por ejemplo, example.com. próximo deberá suscribirse a un servicio CDN de un proveedor de alojamiento en la nube. Cuando usted Para ello, debe configurar el "origen" de la CDN para que apunte a su sitio web example.com, consulte con su proveedor la documentación sobre la configuración del servidor de origen.

La CDN que aprovisionó debería proporcionarle un subdominio personalizado para su aplicación como mycdnsubdomain.fictional-cdn.com (tenga en cuenta que fictional-cdn.com no es un proveedor de CDN válido en el momento de escribir este artículo). Ahora que has configurado su servidor CDN, debe decirle a los navegadores que usen su CDN para obtener activos en lugar de su servidor Rails directamente. Puede hacer esto configurando Rails para establezca su CDN como el host de activos en lugar de utilizar una ruta relativa. Para configurar tu host de activos en Rails, debe configurar config.action_controller.asset_host en config/environment/production.rb:

config.action_controller.asset_host = 'mycdnsubdomain.fictional-cdn.com'

Solo necesita proporcionar el "host", este es el subdominio y la raíz dominio, no es necesario especificar un protocolo o "esquema" como http:// o https://. Cuando se solicita una página web, el protocolo en el enlace a su activo que se genera coincidirá con la forma en que se accede a la página web de forma predeterminada.

También puede establecer este valor a través de un entorno variable para ejecutar una preparar una copia de su sitio más fácilmente:

config.action_controller.asset_host = ENV['CDN_HOST']

Debería configurar CDN_HOST en su servidor en mycdnsubdomain .fictional-cdn.com para que esto funcione.

Una vez que haya configurado su servidor y su CDN cuando atienda una página web que tiene un activo:

<%= asset_path('smile.png') %>

En lugar de devolver una ruta como / assets / smile.png (los resúmenes se omiten para mayor legibilidad). La URL generada tendrá la ruta completa a su CDN.

http://mycdnsubdomain.fictional-cdn.com/assets/smile.png

Si el CDN tiene una copia de smile.png, la servirá al navegador y a su el servidor ni siquiera sabe que se solicitó. Si el CDN no tiene una copia intentará encontrarlo en el "origen" example.com/assets/smile.png y luego almacenar para uso futuro.

Si desea servir solo algunos activos de su CDN, puede usar :host personalizado opción su asistente de activos, que sobrescribe el valor establecido en config.action_controller.asset_host.

<%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>
4.4.2 Customize CDN Caching Behavior

Una CDN funciona almacenando en caché el contenido. Si el CDN tiene contenido obsoleto o incorrecto, entonces es perjudicando en lugar de ayudar a su aplicación. El propósito de esta sección es describir el comportamiento general de almacenamiento en caché de la mayoría de las CDN, su proveedor específico puede comportarse de manera ligeramente diferente.

4.4.2.1 CDN Request Caching

Si bien una CDN se describe como buena para almacenar en caché activos, en realidad almacena en caché el solicitud completa. Esto incluye el cuerpo del activo y los encabezados. los el más importante es Cache-Control que le dice a la CDN (y a los navegadores web) cómo almacenar en caché el contenido. Esto significa que si alguien solicita un activo que no no existe /assets/i-dont-exist.png y su aplicación Rails devuelve un 404, entonces su CDN probablemente almacenará en caché la página 404 si un encabezado Cache-Control válido está presente.

4.4.2.2 CDN Header Debugging

Una forma de verificar que los encabezados estén almacenados en caché correctamente en su CDN es usando curl. Tú puede solicitar los encabezados tanto de su servidor como de su CDN para verificar que sean lo mismo:

$ curl -I http://www.example/assets/application-
d0e099e021c95eb0de3615fd1d8c4d83.css
HTTP/1.1 200 OK
Server: Cowboy
Date: Sun, 24 Aug 2014 20:27:50 GMT
Connection: keep-alive
Last-Modified: Thu, 08 May 2014 01:24:14 GMT
Content-Type: text/css
Cache-Control: public, max-age=2592000
Content-Length: 126560
Via: 1.1 vegur

Frente a la copia CDN.

$ curl -I http://mycdnsubdomain.fictional-cdn.com/application-
d0e099e021c95eb0de3615fd1d8c4d83.css
HTTP/1.1 200 OK Server: Cowboy Last-
Modified: Thu, 08 May 2014 01:24:14 GMT Content-Type: text/css
Cache-Control:
public, max-age=2592000
Via: 1.1 vegur
Content-Length: 126560
Accept-Ranges:
bytes
Date: Sun, 24 Aug 2014 20:28:45 GMT
Via: 1.1 varnish
Age: 885814
Connection: keep-alive
X-Served-By: cache-dfw1828-DFW
X-Cache: HIT
X-Cache-Hits:
68
X-Timer: S1408912125.211638212,VS0,VE0

Consulte la documentación de su CDN para obtener información adicional que puedan proporcionar como X-Cache o para cualquier encabezado adicional que puedan agregar.

4.4.2.3 CDNs and the Cache-Control Header

El encabezado de control de caché es un W3C especificación que describe cómo se puede almacenar en caché una solicitud. Cuando no se utiliza CDN, El navegador utilizará esta información para almacenar en caché el contenido. Esto es muy útil para activos que no se modifican para que un navegador no necesite volver a descargar un CSS o JavaScript del sitio web en cada solicitud. Generalmente queremos nuestro servidor Rails para decirle a nuestra CDN (y navegador) que el activo es "público", es decir, cualquier caché puede almacenar la solicitud. Además, comúnmente queremos establecer max-age, que es cuánto tiempo el caché almacenará el objeto antes de invalidar el caché. La max-age El valor se establece en segundos con un valor máximo posible de 31536000, que es uno. año. Puede hacer esto en su aplicación Rails configurando

config.public_file_server.headers = {
  'Cache-Control' => 'public, max-age=31536000'
}

Ahora, cuando su aplicación sirva a un activo en producción, la CDN almacenará el activo por hasta un año. Dado que la mayoría de las CDN también almacenan en caché los encabezados de la solicitud, esto Cache-Control se transmitirá a todos los navegadores futuros que busquen este activo, el navegador sabe que puede almacenar este activo durante mucho tiempo antes necesitando volver a solicitarlo.

4.4.2.4 CDNs and URL based Cache Invalidation

La mayoría de las CDN almacenan en caché el contenido de un activo en función de la URL completa. Esto significa que una solicitud para

http://mycdnsubdomain.fictional-cdn.com/assets/smile-123.png

Será un caché completamente diferente al

http://mycdnsubdomain.fictional-cdn.com/assets/smile.png

Si desea establecer un max-age en un futuro lejano en su Cache-Control (y lo hace), luego asegúrese de que cuando cambie sus activos, su caché esté invalidado. por ejemplo al cambiar la cara sonriente en una imagen de amarillo a azul, desea todos los visitantes de su sitio para obtener la nueva cara azul. Cuando utilice un CDN con el La canalización de activos de Rails config.assets.digest se establece en true de forma predeterminada para que cada activo tendrá un nombre de archivo diferente cuando se cambie. De esta manera tu no tiene que invalidar nunca manualmente ningún elemento en su caché. Usando un en su lugar, con un nombre de activo único diferente, sus usuarios obtienen el activo más reciente.

5 Customizing the Pipeline

5.1 CSS Compression

Una de las opciones para comprimir CSS es YUI. El YUI CSS compresor proporciona minificación.

La siguiente línea habilita la compresión YUI y requiere el yui-compressor gem.

config.assets.css_compressor = :yui

La otra opción para comprimir CSS si tiene instalada la gema sass-rails es

config.assets.css_compressor = :sass

5.2 JavaScript Compression

Las posibles opciones para la compresión de JavaScript son :closure, :uglifier y :yui. Estos requieren el uso del closure-compiler, uglifier o gemas yui-compressor, respectivamente.

Tome la gema uglifier, por ejemplo. Esta joya envuelve UglifyJS (escrito para NodeJS) en Ruby. Comprime su código eliminando espacios en blanco y comentarios, acortando los nombres de las variables locales y realizando otras microoptimizaciones como como cambiar las declaraciones if y else a operadores ternarios cuando sea posible.

La siguiente línea invoca uglifier para la compresión de JavaScript.

config.assets.js_compressor = :uglifier

Necesitará un ExecJS tiempo de ejecución admitido para usar uglifier. Si está utilizando macOS o Windows tiene un tiempo de ejecución de JavaScript instalado en su sistema operativo.

5.3 GZipping your assets

De forma predeterminada, se generará la versión comprimida con gzip de los activos compilados, junto con la versión sin gzip de los activos. Los activos comprimidos con Gzip ayudan a reducir la transmisión de datos a través del cable. Puede configurar esto estableciendo el indicador gzip.

config.assets.gzip = false # disable gzipped assets generation

Consulte la documentación de su servidor web para obtener instrucciones sobre cómo entregar activos comprimidos con gzip.

5.4 Using Your Own Compressor

The compressor config settings for CSS and JavaScript also take any object. This object must have a compress method that takes a string as the sole argument and it must return a string.

class Transformer
  def compress(string)
    do_something_returning_a_string(string)
  end
end

Para habilitar esto, pase un nuevo objeto a la opción de configuración en application.rb:

config.assets.css_compressor = Transformer.new

5.5 Changing the assets Path

La ruta pública que usa Sprockets por defecto es /assets.

Esto se puede cambiar a otra cosa:

config.assets.prefix = "/some_other_path"

Esta es una opción útil si está actualizando un proyecto anterior que no usó el canalización de activos y ya usa esta ruta o desea usar esta ruta para un nuevo recurso.

5.6 X-Sendfile Headers

El encabezado X-Sendfile es una directiva para que el servidor web ignore la respuesta desde la aplicación y, en su lugar, sirve un archivo especificado desde el disco. Esta opción está desactivado de forma predeterminada, pero se puede habilitar si su servidor lo admite. Cuando está habilitado, esto transfiere la responsabilidad de servir el archivo al servidor web, que es Más rápido. Eche un vistazo a send_file sobre cómo utilizar esta función.

Apache y NGINX admiten esta opción, que se puede habilitar en config/environments/production.rb:

# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

si está actualizando una aplicación existente y tiene la intención de utilizar esta opción, tenga cuidado de pegar esta opción de configuración solo en production.rb y cualquier otro entorno que defina con comportamiento de producción (no application.rb).

Para obtener más detalles, consulte los documentos de su servidor web de producción:

6 Assets Cache Store

De forma predeterminada, Sprockets almacena en caché los activos en tmp/cache/assets en desarrollo y entornos de producción. Esto se puede cambiar de la siguiente manera:

config.assets.configure do |env|
  env.cache = ActiveSupport::Cache.lookup_store(:memory_store,
                                                { size: 32.megabytes })
end

Para deshabilitar el almacén de caché de activos:

config.assets.configure do |env|
  env.cache = ActiveSupport::Cache.lookup_store(:null_store)
end

7 Adding Assets to Your Gems

Los activos también pueden provenir de fuentes externas en forma de gemas.

Un buen ejemplo de esto es la gema jquery-rails. Esta gema contiene una clase de motor que hereda de Rails :: Engine. Al hacer esto, se informa a Rails que el directorio para este gema puede contener activos y os directorios app/assets, lib/assets y vendor/assets de este motor se agregan a la ruta de búsqueda de Sprockets.

8 Making Your Library or Gem a Pre-Processor

Sprockets utiliza procesadores, transformadores, compresores y exportadores para extender Funcionalidad de Sprockets. Mira esto Sprockets extensibles aprender más. Aquí registramos un preprocesador para agregar un comentario al final de archivos de texto/css (.css).

module AddComment
  def self.call(input)
    { data: input[:data] + "/* Hello From my sprockets extension */" }
  end
end

Ahora que tiene un módulo que modifica los datos de entrada, es hora de registrarse como un preprocesador para su tipo de mime.

Sprockets.register_preprocessor 'text/css', AddComment

Comentarios Sobre el Contenido

Las guías de rieles se administran y publican en latinadeveloper/railsguides.es en GitHub.

Si lee esta guía y encuentra algún texto o código incorrecto que le interese, no dude en enviar una solicitud de extracción en el repositorio anterior. Consulte el archivo README en GitHub para saber cómo enviar una solicitud de extracción. Please contribute if you see any typos or factual errors.