Saltar al contenido

¿Cómo importar una carpeta completa de imágenes SVG (o cómo cargarlas dinámicamente) en una aplicación web React?

Solución:

Si usa React, sospecho firmemente que también está usando Webpack. Puedes usar require.context en lugar de es6 import y Webpack lo resolverá por usted cuando cree.

require.context ( folder, recurse, pattern )
  • carpeta – Cadena – Ruta a la carpeta para comenzar a buscar archivos.
  • recurse: booleano: si se debe escanear la carpeta de forma recursiva.
  • pattern – RegExp – Patrón coincidente que describe qué archivos incluir.

La primera línea de cada ejemplo …

const reqSvgs = require.context ( './images', true, /.svg$/ )

… crea un mapeo de contexto requerido para todos los *.svg rutas de archivo en el images carpeta a una importación. Esto nos da una función de requisito especializada llamada reqSvgs con algunas propiedades adjuntas.

Una de las propiedades de reqSvgs es un keys método, que devuelve una lista de todas las rutas de archivo válidas.

const allSvgFilepaths = reqSvgs.keys ()

Podemos pasar una de esas rutas de archivo a reqSvgs para obtener una imagen importada.

const imagePath = allSvgFilePaths[0]
const image = reqSvgs ( imagePath )

Esta API es restrictiva y poco intuitiva para este caso de uso, por lo que sugiero convertir la colección a una estructura de datos JavaScript más común para facilitar el trabajo.

Cada imagen se importará durante la conversión. Tenga cuidado, ya que esto podría ser un arma de fuego. Pero proporciona un mecanismo razonablemente simple para copiar varios archivos a la carpeta de compilación, a la que es posible que nunca se haga referencia explícita en el resto de su código fuente.

A continuación, se muestran 3 conversiones de ejemplo que pueden resultarle útiles.


Formación

Cree una matriz de los archivos importados.

const reqSvgs = require.context ( './images', true, /.svg$/ )
const paths = reqSvgs.keys ()

const svgs = paths.map( path => reqSvgs ( path ) )

Matriz de objetos

Cree una matriz de objetos, con cada objeto { path, file } para una imagen.

const reqSvgs = require.context ( './images', true, /.svg$/ )

const svgs = reqSvgs
  .keys ()
  .map ( path => ({ path, file: reqSvgs ( path ) }) )

Objeto llano

Cree un objeto donde cada ruta sea una clave para su archivo coincidente.

const reqSvgs = require.context ('./images', true, /.svg$/ )

const svgs = reqSvgs
  .keys ()
  .reduce ( ( images, path ) => {
    images[path] = reqSvgs ( path )
    return images
  }, {} )

SurviveJS da un ejemplo más generalizado de require.context aquí SurviveJS Webpack Dynamic Loading.

Me encontré con este problema: inicialmente tenía la “respuesta aceptada”, pero causé una solicitud http para todos y cada uno de los svg, lo que provocó un límite de velocidad. Así que terminé con una combinación de la respuesta aceptada y lo que propuso @karthik: usar un cargador en el request.context

A partir de CRA 2.0, @svgr se incluye para importar svg como componentes de reacción.

const reqSvgs = require.context('[email protected]/webpack!flag-icon-css/flags/4x3', true, /.svg$/)

Entonces aquí combinamos un cargador svg y require.context

const flagMap = reqSvgs.keys().reduce((images, path) => {
  const key = path.substring(path.lastIndexOf("https://foroayuda.es/") + 1, path.lastIndexOf('.'))
  images[key] = reqSvgs(path).default
  return images
}, {})

Luego mapeamos todos estos en un objeto json para que podamos usar la búsqueda de claves

Para renderizar svg en jsx:

const Flag = flagMap['dk']
return (
  <Flag />
)

Y días felices, svgs incluidos en el paquete y sin solicitudes http individuales

En lugar de varios archivos SVG, puede utilizar un único objeto SVG.

El sprite SVG se puede generar desde un directorio de archivos SVG usando svg-sprite-generator:

svg-sprite-generate -d images -o images/sprite.svg

Entonces úsalo así:

import React from 'react';
import { NavLink } from 'react-router-dom';
import sprite from './images/sprite.svg';

export default (props) => (
  <NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}>
    <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30">
      <use xlinkHref={`${sprite}#${props.itemName}`} />
    </svg>
  </NavLink>
)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *