웹팩을 사용하여 디렉토리에서 동적으로 이미지 가져 오기


104

따라서 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} />

특정 디렉토리의 모든 파일을 이름 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']} />

8
나는 그런 .map종류의 반환 값을 기대 한다는 것을 지적하고 싶습니다 . 귀하의 경우에는 forEach대신 좋은 ol '을 사용합니다.
Bram Vanroy

1
@BramVanroy하거나 그것에게 한 줄을 반환 r.keys.().map(...)... 직접
LinusGeffarth

답변:


124

특정 디렉토리의 모든 파일을 이름 sans 확장자로 동적으로 가져온 다음 필요에 따라 해당 파일을 사용할 수있는 방법이 있어야한다고 생각합니다.

ES6에는 없습니다. 의 요점 importexport그 종속성을 판단 할 수 있습니다 정적 즉, 코드를 실행하지 않고,.

그러나 웹팩을 사용하고 있으므로 require.context. 다음을 수행 할 수 있어야합니다.

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

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

흥미 롭습니다 ... 그래서 저는 현재 웹팩 구성에서 '파일 로더'를 사용하여 모든 파일을 앱 공개 디렉토리의 단일 위치로 이동하고 있습니다. 여기서는 일어나지 않습니다. 로더는 require.context에서 어떻게 작동합니까?
klinore 2017

1
"여기서는 그런 일이 없습니다" 파일이 출력 폴더에 나타나지 않는다는 뜻입니까? 그래도 위의 코드로 경로를 얻습니까? 나는 ...이 지원하기 위해 수행 아무것도 특별한 일이 필요하다 생각하지 않는다
펠릭스 클링

2
왜 그런지 모르겠지만, 내 로더를 구매하지 않고 원래 경로를 얻었습니다. 로더가 이제 제대로 작동하고 있으며 올바른 경로가 제공되고 있습니다! 대박. require.context에 소개 해주셔서 감사합니다 : D!
klinore

1
create-react-app (cra)가있는 경우 어떻게해야합니까? 의는 cra importAll아무 것도 반환하지 않습니다.
giorgim

2
이것은 나를 위해 작동하지만 TypeScript에서 동일한 것을 어떻게 작성합니까? 올바른 유형은 무엇입니까?
Maximilian Lindsey

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
webpack으로이 작업을 수행하려면 더 많은 작업이 필요하다고 생각합니다.
Felix Kling

여기에 웹팩 구성 파일을 붙여 넣을 수 있습니까?
Robsonsjre

3
이것은 영광 스럽습니다. 감사!
poweratom

1
나는 이와 같은 글로벌 요구 사항을 사용하는 것을 권장하지 않습니다 -eslint.org/docs/rules/global-require
markyph

7

au.png, nl.png 등과 같은 이름의 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)$/)
);

감사합니다! 완벽하게 작동합니다!
Zakalwe

4

업데이트 질문을 잘 이해하지 못한 것 같습니다. @Felix가 맞았으므로 대답을 확인하십시오. 다음 코드는 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은이를 구문 분석하고 필요한 파일을로드합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.