web-dev-qa-db-fra.com

Importer dynamiquement des images d'un répertoire à l'aide de Webpack

Alors, voici mon flux de travail actuel pour importer des images et des icônes dans Webpack via ES6:

import cat from './images/cat1.jpg'
import cat2 from './images/cat2.svg'
import doggy from './images/doggy.png'
import turtle from './images/turtle.png'

<img src={doggy} />

Cela devient vite brouillon. Voici ce que je veux:

import * from './images'

<img src={doggy} />
<img src={turtle} />

Je pense qu'il doit exister un moyen d'importer dynamiquement tous les fichiers d'un répertoire spécifique sous leur nom sans extension, puis de les utiliser au besoin.

Quelqu'un a vu cela ou avez-vous une idée de la meilleure façon de procéder?


PDATE:

En utilisant la réponse sélectionnée, j'ai pu faire ceci:

function importAll(r) {
  let images = {};
  r.keys().map((item, index) => { images[item.replace('./', '')] = r(item); });
  return images;
}

const images = importAll(require.context('./images', false, /\.(png|jpe?g|svg)$/));

<img src={images['doggy.png']} />
72
klinore

Je pense qu'il doit exister un moyen d'importer dynamiquement tous les fichiers d'un répertoire spécifique sous leur nom sans extension, puis de les utiliser au besoin.

Pas dans ES6. L’intérêt de import et export est que les dépendances peuvent être déterminées statiquement , c’est-à-dire sans exécuter de code.

Mais puisque vous utilisez webpack, regardez require.context . Vous devriez pouvoir faire ce qui suit:

_function importAll(r) {
  return r.keys().map(r);
}

const images = importAll(require.context('./', false, /\.(png|jpe?g|svg)$/));
_
89
Felix Kling

C'est facile. Vous pouvez utiliser require (une méthode statique, l'importation ne concerne que les fichiers dynamiques) à l'intérieur de render. Comme dans l'exemple ci-dessous:

render() {
    const {
      someProp,
    } = this.props

    const graphImage = require('./graph-' + anyVariable + '.png')
    const tableImage = require('./table-' + anyVariable2 + '.png')

    return (
    <img src={graphImage}/>
    )
}
8
Robsonsjre

J'ai un répertoire de drapeaux de pays png nommé comme au.png, nl.png etc. J'ai donc:

-svg-country-flags
 --png100px
   ---au.png
   ---au.png
 --index.js
 --CountryFlagByCode.js

index.js

const context = require.context('./png100px', true, /.png$/);

const obj = {};
context.keys().forEach((key) => {
  const countryCode = key.split('./').pop() // remove the first 2 characters
    .substring(0, key.length - 6); // remove the file extension
  obj[countryCode] = context(key);
});

export default obj;

J'ai lu un fichier comme ça:

CountryFlagByCode.js

import React from 'react';
import countryFlags from './index';

const CountryFlagByCode = (countryCode) => {
    return (
        <div>
          <img src={countryFlags[countryCode.toLowerCase()]} alt="country_flag" />
        </div>
      );
    };

export default CountryFlagByCode;
5
Tudor Morar

UPDATE Il semble que je n’ai pas bien compris la question. @Felix a bien compris, alors vérifie sa réponse. Le code suivant fonctionnera dans un environnement Nodejs uniquement.

Ajouter un fichier index.js dans le dossier images

const testFolder = './';
const fs = require('fs');
const path = require('path')

const allowedExts = [
  '.png' // add any extensions you need
]

const modules = {};

const files = fs.readdirSync(testFolder);

if (files && files.length) {
  files
    .filter(file => allowedExts.indexOf(path.extname(file)) > -1)
    .forEach(file => exports[path.basename(file, path.extname(file))] = require(`./${file}`));
}

module.exports = modules;

Cela vous permettra d'importer tout ce qui se trouve dans un autre fichier et Wepback l'analysera et chargera les fichiers requis.

3
kbariotis

Une approche fonctionnelle pour résoudre ce problème:

const importAll = require =>
  require.keys().reduce((acc, next) => {
    acc[next.replace("./", "")] = require(next);
    return acc;
  }, {});

const images = importAll(
  require.context("./image", false, /\.(png|jpe?g|svg)$/)
);
1
Patrick Santos