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

IT技术 reactjs webpack ecmascript-6
2021-04-05 23:45:31

所以这是我当前通过 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} />

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

import * from './images'

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

我觉得必须有某种方法可以将特定目录中的所有文件动态导入为它们的名称 sans 扩展名,然后根据需要使用这些文件。

任何人都见过这样做,或者对最好的方法有任何想法?


更新:

使用选定的答案,我能够做到这一点:

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']} />
6个回答

我觉得必须有某种方法可以将特定目录中的所有文件动态导入为它们的名称 sans 扩展名,然后根据需要使用这些文件。

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

但是由于您使用的是 webpack,请查看require.context. 您应该能够执行以下操作:

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

const images = importAll(require.context('./', false, /\.(png|jpe?g|svg)$/));
如果我有 create-react-app(cra) 该怎么用?cra importAll返回什么。
2021-05-24 23:45:31
“这里没有发生”您的意思是文件没有出现在输出文件夹中?但是,您仍然使用上述代码获得它们的路径吗?我认为不需要做任何特别的事情来支持这一点......
2021-05-28 23:45:31
这对我有用,但你会如何在 TypeScript 中写同样的东西?它的正确类型是什么?
2021-06-06 23:45:31
如果有人想知道如何使用返回的数组,那么返回数组中的每一项都会有一个对象default作为键,可以直接用作<img src={item.default} />
2021-06-10 23:45:31
不知道为什么,我的装载机没有运行,我得到了原来的路径。加载器现在工作正常,并且提供了正确的路径!惊人的。感谢您介绍 require.context :D!
2021-06-13 23:45:31

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

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)$/)
);

这简单。您可以requirerender. 像下面的例子:

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

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

    return (
    <img src={graphImage}/>
    )
}
你能把你的 webpack 配置文件粘贴在这里吗?
2021-05-29 23:45:31
我不建议使用这样的全局要求 - 请参阅eslint.org/docs/rules/global-require
2021-06-04 23:45:31
我认为需要做更多的工作才能使 webpack 工作。
2021-06-15 23:45:31

我有名为 au.png、nl.png 等的 png 国家标志目录。所以我有:

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

索引.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;

我读了一个这样的文件:

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;

更新 好像我不太明白这个问题。@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;

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