डायनामिक रूप से वेबपैक का उपयोग करके डायरेक्टरी से चित्र आयात करें


99

इसलिए यहाँ 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} />

इससे गड़बड़ जल्दी हो जाती है। यहाँ मैं क्या चाहता हूँ:

import * from './images'

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

मुझे लगता है कि किसी विशेष निर्देशिका से सभी फाइलों को डायनामिक रूप से आयात करने का कोई तरीका होना चाहिए क्योंकि उनके नाम का विस्तार होता है, और फिर आवश्यकतानुसार उन फाइलों का उपयोग करना चाहिए।

किसी ने भी इसे किया है, या इसके बारे में जाने के सर्वोत्तम तरीके पर कोई विचार है?


अपडेट करें:

चयनित उत्तर का उपयोग करते हुए, मैं ऐसा करने में सक्षम था:

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

7
मैं इस तरह का संकेत देना चाहता हूं कि .mapरिटर्न वैल्यू की उम्मीद है। आपके मामले में, एक अच्छे ol 'का उपयोग करेगा forEach
ब्रैम वनरॉय

1
@BramVanroy या बस इसे वन-लाइनर r.keys.().map(...)
बनाएं

जवाबों:


120

मुझे लगता है कि किसी विशेष निर्देशिका से सभी फाइलों को डायनामिक रूप से आयात करने का कोई तरीका होना चाहिए क्योंकि उनके नाम का विस्तार होता है, और फिर आवश्यकतानुसार उन फाइलों का उपयोग करना चाहिए।

ES6 में नहीं। पूरे बिंदु importऔर exportयह है कि निर्भरता को सांख्यिकीय रूप से निर्धारित किया जा सकता है , अर्थात कोड को निष्पादित किए बिना।

लेकिन जब से आप वेबपैक का उपयोग कर रहे हैं, एक नज़र डालें require.context। आपको निम्नलिखित कार्य करने में सक्षम होना चाहिए:

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

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

दिलचस्प है ... इसलिए, मैं वर्तमान में अपने वेबपैक कॉन्फिगर में 'फाइल-लोडर' का उपयोग कर रहा हूं, उन सभी फाइलों को अपने एप्स पब्लिक डायर में एक ही स्थान पर स्थानांतरित करने के लिए। यह यहाँ नहीं हो रहा है। आवश्यकता के साथ लोडर कैसे काम करते हैं। संदर्भ?
क्लिनोर

1
"यह यहाँ नहीं हो रहा है" आप आउटपुट फ़ोल्डर में दिखाई देने वाली फ़ाइलों का मतलब नहीं है? क्या आप अभी भी उपरोक्त कोड के साथ उनके लिए रास्ता प्राप्त करते हैं? मुझे नहीं लगता कि इसका समर्थन करने के लिए कुछ खास करने की जरूरत है ...
फेलिक्स क्लिंग

2
निश्चित नहीं कि क्यों, मेरा लोडर नहीं खरीदा जा रहा था और मुझे मूल रास्ता मिल रहा था। लोडर अब ठीक काम कर रहा है और सही रास्ता प्रदान किया जा रहा है! बहुत बढ़िया। आवश्यकता में परिचय के लिए धन्यवाद। संदर्भ: डी!
18-28 पर klinore

1
यदि मेरे पास रिएक्शन-ऐप (क्रेफ़) है तो क्या करें? में cra importAllकुछ भी नहीं लौटे।
जियोर्जिम

2
यह मेरे लिए काम करता है, लेकिन आप टाइपस्क्रिप्ट में एक ही बात कैसे लिखेंगे? इसके लिए सही प्रकार क्या होगा?
मैक्सिमिलियन लिंडसे

10

यह आसान है। आप require(एक स्थैतिक विधि का उपयोग कर सकते हैं , आयात सिर्फ डायनेमिक फ़ाइलों के लिए है) render। नीचे दिए गए उदाहरण की तरह:

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

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

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

1
मुझे लगता है कि वेबपैक के साथ इस काम को करने के लिए और अधिक करने की आवश्यकता है।
फेलिक्स क्लिंग

क्या आप अपना वेबपैक कॉन्फिगर फाइल यहाँ पेस्ट कर सकते हैं?
रॉबन्संज्रे

3
यह गौरवशाली है। धन्यवाद!
पावरटॉम

1
मैं इस तरह की वैश्विक आवश्यकताओं का उपयोग करने की सलाह नहीं दूंगा
eslint.org/docs/rules/global-require

7

मेरे पास png देश के झंडे जैसे au.png, nl.png आदि की निर्देशिका है, इसलिए मेरे पास है:

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

मैंने एक फाइल इस तरह पढ़ी:

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

इस समस्या को हल करने के लिए एक कार्यात्मक दृष्टिकोण:

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

धन्यवाद! अच्छी तरह से काम!
ज़कलेव

4

अपडेट करें ऐसा लगता है जैसे मैं सवाल समझ में नहीं आया। @ फेलिक्स को यह सही लगा तो उसके जवाब की जाँच करें। निम्न कोड केवल Nodejs वातावरण में काम करेगा।

फ़ोल्डर index.jsमें एक फ़ाइल जोड़ें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;

यह आपको दूसरी फ़ाइल से सब कुछ आयात करने की अनुमति देगा और Wepback इसे पार्स करेगा और आवश्यक फ़ाइलों को लोड करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.