Dynamically import images from a directory using w

2019-01-04 08:31发布

So here's my current workflow for importing images and icons in 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} />

This gets messy quick. Here's what I want:

import * from './images'

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

I feel like there must be some way to dynamically import all files from a specific directory as their name sans extension, and then use those files as needed.

Anyone seen this done, or have any thoughts on the best way to go about it?


UPDATE:

Using the selected answer, I was able to do this:

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']} />

5条回答
我命由我不由天
2楼-- · 2019-01-04 08:33

UPDATE It seems like I didnt quite understand the question. @Felix got it right so check his answer. The following code will work in a Nodejs environment only.

Add an index.js file in the images folder

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;

This will allow you to import everything from another file and Wepback will parse it and load the required files.

查看更多
在下西门庆
3楼-- · 2019-01-04 08:42

It's easy. You can use require (a static method, import is just for dynamic files) inside the render. Like the example below:

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

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

    return (
    <img src={graphImage}/>
    )
}
查看更多
小情绪 Triste *
4楼-- · 2019-01-04 08:44

I have directory of png country flags named like au.png, nl.png etc. So I have:

-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;

I read a file like this:

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;
查看更多
SAY GOODBYE
5楼-- · 2019-01-04 08:47

A functional approach to solve this problem:

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)$/)
);
查看更多
男人必须洒脱
6楼-- · 2019-01-04 08:57

I feel like there must be some way to dynamically import all files from a specific directory as their name sans extension, and then use those files as needed.

Not in ES6. The whole point of import and export is that dependencies can be determined statically, i.e. without executing code.

But since you are using webpack, have a look at require.context . You should be able to do the following:

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

const images = importAll(require.context('./', false, /\.(png|jpe?g|svg)$/));
查看更多
登录 后发表回答