使用webpack从目录动态导入图像

kli*_*ore 77 ecmascript-6 reactjs webpack

所以这是我目前通过ES6在webpack中导入图像和图标的工作流程:

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} />
Run Code Online (Sandbox Code Playgroud)

这很快变得混乱.这就是我想要的:

import * from './images'

<img src={doggy} />
<img src={turtle} />
Run Code Online (Sandbox Code Playgroud)

我觉得必须有一些方法动态导入特定目录中的所有文件,因为他们的名称没有扩展名,然后根据需要使用这些文件.

有人看过这个,或者对最好的方法有任何想法吗?


更新:

使用选定的答案,我能够这样做:

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']} />
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 93

我觉得必须有一些方法动态导入特定目录中的所有文件,因为他们的名称没有扩展名,然后根据需要使用这些文件.

不在ES6中.整点importexport是依赖关系可被确定静态,即没有执行代码.

但是既然你正在使用webpack,请看一下require.context.您应该能够执行以下操作:

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

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

  • 不知道为什么,买我的装载机没有运行,我得到了原来的路径.装载机现在工作正常,正在提供正确的路径!真棒.感谢您介绍require.context:D! (2认同)
  • 这对我有用,但是你如何用 TypeScript 编写同样的东西呢?它的正确类型是什么? (2认同)

小智 10

解决这个问题的函数式方法:

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)$/)
);
Run Code Online (Sandbox Code Playgroud)


Rob*_*jre 9

这简单。您可以在中使用require(静态方法,导入仅用于动态文件)render。像下面的例子:

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

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

    return (
    <img src={graphImage}/>
    )
}
Run Code Online (Sandbox Code Playgroud)

  • 这是光荣的。谢谢! (3认同)

Dan*_*ram 7

这是我在 Reactjs 中制作的一个功能组件,用于使用 webpack 文档和此处的一些答案简单地显示我的项目中文件夹内的所有图像media(与组件相同级别)。

import React from 'react';

const cache = {};

function importAll(r) {
    r.keys().forEach((key) => (cache[key] = r(key)));
}
// Note from the docs -> Warning: The arguments passed to require.context must be literals!
importAll(require.context("./media", false, /\.(png|jpe?g|svg)$/));

const images = Object.entries(cache).map(module => module[1].default);


const MediaPage = () => {
    return (
        <>
            <p>Media Page..</p>

            {images.map(image => (
                <img style={{width: 100}} src={image} />
            ))}
        </>
    );
}

export default MediaPage;
Run Code Online (Sandbox Code Playgroud)

从媒体目录渲染图像

通过我加载图像的方式,从cache对象映射时文件名会丢失,但如果您需要它们,您可以直接使用cache对象,因为键是文件名。

// example with styles just for clarity
return (
    <>
        <p>Media Page..</p>

        {Object.entries(cache).map(module => {
            const image = module[1].default;
            const name = module[0].replace("./","");
            return (
                <div style={{float: 'left', padding: 10, margin: 10, border: '2px solid white' }}>
                    <img style={{width: 100, margin: 'auto', display: 'block'}} src={image} />
                    <p>{name}</p>
                </div>
            )
        })}
    </>
);
Run Code Online (Sandbox Code Playgroud)

带文件名的图像


kba*_*tis 5

更新 似乎我不太明白这个问题。@Felix 做对了,所以检查他的答案。以下代码仅适用于 Nodejs 环境。

index.jsimages文件夹中添加一个文件

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;
Run Code Online (Sandbox Code Playgroud)

这将允许您从另一个文件导入所有内容,Wepback 将解析它并加载所需的文件。


Tud*_*rar 5

我有png国家标志的目录,如au.png,nl.png等。所以我有:

-svg-country-flags
 --png100px
   ---au.png
   ---au.png
 --index.js
 --CountryFlagByCode.js
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

我读了这样的文件:

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;
Run Code Online (Sandbox Code Playgroud)