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:
-
** 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é.
-
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.
-
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 comoasset_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.
2.3 Coding Links to Assets
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")
devuelveurl(/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")
devuelveurl(/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.