Skip to content

Más allá de la velocidad

ViteConf 2023

¡Mira la repetición!

Gestión de recursos estáticos

Importar recursos como URL

Importar un recurso estático retornará la URL pública que es resuelta al servirla:

js
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

Por ejemplo, imgUrl será /img.png durante el desarrollo y se convertirá en /assets/img.2d8efhg.png en la compilación de producción.

El comportamiento es similar al file-loader de webpack. La diferencia es que la importación puede ser usando rutas públicas absolutas (basadas en la raíz del proyecto durante el desarrollo) o rutas relativas.

  • Las referencias url() en CSS se manejan de la misma manera.

  • Si usa el complemento de Vue, las referencias de recursos en las plantillas de Vue SFC se convierten automáticamente en importaciones.

  • Los tipos de archivos comunes de imágenes, medios y fuentes se detectan como recursos automáticamente. Puedes ampliar la lista interna utilizando la opción assetsInclude.

  • Los recursos referenciados se incluyen como parte del gráfico de compilación de recursos, obtendrán nombres de archivo con hash y los complementos pueden procesarlos para su optimización.

  • Los recursos más pequeños en bytes que la opción assetsInlineLimit se insertarán como URL de datos en base64.

  • Los marcadores de posición de Git LFS se excluyen automáticamente de la inserción porque no contienen el contenido del archivo que representan. Para obtener la inserción, asegúrate de descargar el contenido del archivo a través de Git LFS antes de compilar.

  • TypeScript, de forma predeterminada, no reconoce las importaciones de recursos estáticos como módulos válidos. Para solucionar esto, incluye vite/client.

Importaciones de URL explícita

Los recursos que no están incluidos en la lista interna o en assetsInclude, se pueden importar explícitamente como una URL usando el sufijo ?url. Esto es útil, por ejemplo, para importar los Houdini Paint Worklets.

js
import workletURL from 'extra-scalloped-border/worklet.js?url'
CSS.paintWorklet.addModule(workletURL)

Importar recursos como cadenas de texto

Los recursos pueden ser importados como cadenas de texto usando el sufijo ?raw.

js
import shaderString from './shader.glsl?raw'

Importar scripts como Worker

Los scripts pueden ser importados como workers web con los sufijos ?worker o ?sharedworker.

js
// Fragmento separado en la compilación de producción
import Worker from './shader.js?worker'
const worker = new Worker()
js
// sharedworker
import SharedWorker from './shader.js?sharedworker'
const sharedWorker = new SharedWorker()
js
// En línea como cadena base64
import InlineWorker from './shader.js?worker&inline'

Consulta la sección Web Worker para obtener más detalles.

La carpeta public

Si tienes recursos que:

  • No han sido referenciados en el código fuente (por ejemplo, robots.txt)
  • Deban conservar exactamente el mismo nombre de archivo (sin hash)
  • ...o simplemente no quieres tener que importar un recurso primero solo para obtener su URL

Entonces puedes colocar el recurso en una carpeta public especial en la raíz de tu proyecto. Los recursos en ella se servirán en la ruta raíz / durante el desarrollo y se copiarán en la raíz de la carpeta dist tal como están.

El directorio predeterminado es <root>/public, pero esto se puede configurar a través de la opción publicDir.

Ten en cuenta que:

  • Siempre debes hacer referencia a los recursos de public utilizando la ruta raíz absoluta; por ejemplo, public/icon.png debe estar referenciado en el código fuente como /icon.png.
  • Los recursos en public no se pueden importar desde JavaScript.

new URL(url, import.meta.url)

import.meta.url es una característica nativa de ESM que expone la URL del módulo actual. Combinándolo con el constructor de URL nativo, podemos obtener la URL completa y resuelta de un recurso estático utilizando la ruta relativa de un Módulo JavaScript:

js
const imgUrl = new URL('./img.png', import.meta.url).href

document.getElementById('hero-img').src = imgUrl

Esto funciona de forma nativa en los navegadores modernos; de hecho, Vite no necesita procesar este código durante el desarrollo.

Este patrón también admite direcciones URL dinámicas a través de literales de plantilla:

js
function getImageUrl(name) {
  return new URL(`./dir/${name}.png`, import.meta.url).href
}

Durante la compilación en producción, Vite realizará las transformaciones necesarias para que las URL sigan apuntando a la ubicación correcta incluso después del empaquetado y el hashing de recursos. Sin embargo, la cadena de texto de URL debe ser estática la cual permita ser analizada, de otro modo el codigo permanecerá como está, causando errores en tiempo de ejecución si build.target no soporta import.meta.url.

js
// Vite will not transform this
const imgUrl = new URL(imagePath, import.meta.url).href

Nota: No funciona con SSR

Este patrón no funciona si estás utilizando Vite para Server-Side Rendering, porque import.meta.url tiene una semántica diferente en navegadores con respecto a Node.js. El empaquetado del servidor tampoco puede determinar la URL del host del cliente con anticipación.

Publicado bajo licencia MIT. (31993f54)