require 문없이 웹팩을 사용하여 디렉토리의 모든 파일을로드하는 방법


95

내 앱에 많은 양의 자바 스크립트 파일이 4 개의 하위 디렉토리로 분할되어 있습니다. grunt에서 나는 그것들을 모두 잡고 하나의 파일로 컴파일합니다. 이러한 파일에는 module.exports 기능이 없습니다.

webpack을 사용하여 4 부분으로 나누고 싶습니다. 수동으로 들어가서 모든 파일을 요구하고 싶지 않습니다.

컴파일시 디렉토리 트리를 탐색 한 다음 모든 .js 파일 이름과 경로를 가져온 다음 하위 디렉토리의 모든 파일을 요구하고 출력에 추가하는 플러그인을 만들고 싶습니다.

각 디렉토리의 모든 파일을 진입 점 파일에서 요구할 수있는 모듈로 컴파일하거나 http://webpack.github.io/docs/plugins.html에서 언급 하는 자산에 포함시키고 싶습니다 .

새 파일을 추가 할 때 파일을 올바른 디렉토리에 놓고 포함 할 것인지 알고 싶습니다.

웹팩이나 누군가가이 작업을 위해 작성한 플러그인으로이 작업을 수행하는 방법이 있습니까?

답변:


119

이것이 내가 이것을 달성하기 위해 한 일입니다.

function requireAll(r) { r.keys().forEach(r); }
requireAll(require.context('./modules/', true, /\.js$/));

사용할 로더를 지정하는 방법이 있습니까? 내 사용 사례는 image-size-loader올바른 종횡비로 자리 표시자를 만들기 위해 모든 이미지에을 사용하고 싶습니다 .
bobbaluba 2015

13
당신은 당신이 샘플 webpack.config.js 작업 제공 할 수
Rizwan 파텔

2
@bobbaluba, 구성 파일에서 로더를 지정할 수 있습니다 : loaders: [ { test: /\.json$/, loader: 'json' } ]. { test: /\.json$/, loader: 'json' }로더를 설치 한 경우 .json 파일에 대한 json 로더를 추가합니다.
Jake

1
호출하는 함수를 작성하여 여기에서 DRY를 시도 require.context(...)하면 (예 : 여러 폴더에있는 모든 것을 요구하려는 경우) webpack이 경고를 표시합니다. 인수 require.context는 컴파일 타임 상수 여야합니다.
Isaac Lyman

3
@Joel npmjs.com/package/require-context은 2017 년에 만들어졌습니다 그리고 그것이 바로 거기에서 촬영하고 있다고하기 어렵다, 그래서 내 대답은 2015 년부터이다. 또한을 require-context둘러싼 래퍼 webpack이며 샘플은 2016 년에 추가 된 webpack.js.org/guides/dependency-management/#context-module-apiwebpack 의 문서에서 가져 왔습니다 ( github.com/webpack/있음). webpack.js.org/commit/… ), 또한 내 답변을 작성한 후 ... 아마도 webpack의 작성자가 내 답변에 영향을 받았을 것입니다. 캐시를 갖도록 확장했습니다.
splintor

38

내 앱 파일에서 나는 요구 사항을 넣었습니다.

require.context(
  "./common", // context folder
  true, // include subdirectories
  /.*/ // RegExp
)("./" + expr + "")

이 게시물 제공 : https://github.com/webpack/webpack/issues/118

이제 모든 파일을 추가하고 있습니다. html 및 css 용 로더가 있으며 잘 작동하는 것 같습니다.


27
expr이 예에는 무엇이 있습니까?
twiz

2
expr컨텍스트 폴더 내의 단일 파일에 대한 경로입니다. 따라서 모든 html 파일이 필요한 것이 아니라이 작업을 수행해야하는 경우 유용합니다. webpack.github.io/docs/context.html#context-module-api
mkoryak

18
exprwebpack 문서를 살펴본 후에도 기반 주장이 여기에서 무엇을하고 있는지는 아직 명확하지 않습니다 . "모든 html 파일을 요구하는 것이 아니라"는 의미는 무엇입니까? 여러분 감사합니다
mikkelrd

3
내가 가지고 정의되지 않은 EXPR : catch되지 않은 오류 ReferenceError를 . 그것에 대한 힌트가 있습니까?
CSchulz

2
expr여기에서 의미 하는 바에 대한 답변이 아직 없습니다
wizulus

5

폴더에있는 모든 파일의 맵은 어떻습니까?

// { 
//   './image1.png':  'data:image/png;base64,iVBORw0KGgoAAAANS',
//   './image2.png':  'data:image/png;base64,iVBP7aCASUUASf892',
// }

이 작업을 수행:

const allFiles = (ctx => {
    let keys = ctx.keys();
    let values = keys.map(ctx);
    return keys.reduce((o, k, i) => { o[k] = values[i]; return o; }, {});
})(require.context('./path/to/folder', true, /.*/));

이 예제를 삭제 해 주셔서 감사합니다. map을 사용하여 각 파일이 내 보낸 값을 간단히 반환합니다 =).
cacoder

1

현재 폴더에있는 모든 이미지의지도를 얻는 방법의 예입니다.

const IMAGES_REGEX = /\.(png|gif|ico|jpg|jpeg)$/;

function mapFiles(context) {
  const keys = context.keys();
  const values = keys.map(context);
  return keys.reduce((accumulator, key, index) => ({
    ...accumulator,
    [key]: values[index],
  }), {});
}

const allImages = mapFiles(require.context('./', true, IMAGES_REGEX));

1

@splintor의 모든 장점 (감사합니다).

그러나 여기에는 내 자신의 파생 버전이 있습니다.

혜택:

  • 어떤 모듈 내보내기가 {module_name: exports_obj}개체 아래에 수집됩니다 .
    • module_name 은 파일 이름으로 빌드됩니다.
    • ... 확장자없이 슬래시를 밑줄로 대체합니다 (하위 디렉토리 스캔의 경우).
  • 쉽게 사용자 정의 할 수 있도록 주석을 추가했습니다.
    • 즉, 루트 수준 모듈에 수동으로 필요한 파일이있는 경우 하위 디렉터리에 파일을 포함하지 않을 수 있습니다 .

편집 : 저처럼 모듈이 (적어도 루트 수준에서) 일반 자바 스크립트 객체 이외의 다른 것을 반환하지 않는다고 확신하는 경우 원래 디렉토리 구조를 복제하여 "마운트"할 수도 있습니다 ( 코드 (Deep Version 참조) ) 섹션).

코드 (원래 버전) :

function requireAll(r) {
    return Object.fromEntries(
        r.keys().map(function(mpath, ...args) {
            const result =  r(mpath, ...args);
            const name = mpath
                .replace(/(?:^[.\/]*\/|\.[^.]+$)/g, '') // Trim
                .replace(/\//g, '_') // Relace '/'s by '_'s
            ;
            return [name, result];
        })
    );
};
const allModules = requireAll(require.context(
    // Any kind of variables cannot be used here
    '@models'  // (Webpack based) path
    , true     // Use subdirectories
    , /\.js$/  // File name pattern
));

예:

최종 결과에 대한 샘플 출력 console.log(allModules);:

{
  main: { title: 'Webpack Express Playground' },
  views_home: {
    greeting: 'Welcome to Something!!',
    title: 'Webpack Express Playground'
  }
}

디렉토리 트리 :

models
├── main.js
└── views
    └── home.js

코드 (딥 버전) :

function jsonSet(target, path, value) {
    let current = target;
    path = [...path]; // Detach
    const item = path.pop();
    path.forEach(function(key) {
        (current[key] || (current[key] = {}));
        current = current[key];
    });
    current[item] = value;
    return target;
};
function requireAll(r) {
    const gather = {};
    r.keys().forEach(function(mpath, ...args) {
        const result =  r(mpath, ...args);
        const path = mpath
            .replace(/(?:^[.\/]*\/|\.[^.]+$)/g, '') // Trim
            .split('/')
        ;
        jsonSet(gather, path, result);
    });
    return gather;
};
const models = requireAll(require.context(
    // Any kind of variables cannot be used here
    '@models'  // (Webpack based) path
    , true     // Use subdirectories
    , /\.js$/  // File name pattern
));

예:

이 버전을 사용한 이전 예제의 결과 :

{
  main: { title: 'Webpack Express Playground' },
  views: {
    home: {
      greeting: 'Welcome to Something!!',
      title: 'Webpack Express Playground'
    }
  }
}

0

이것은 나를 위해 작동합니다.

function requireAll(r) { r.keys().forEach(r); } 

requireAll(require.context('./js/', true, /\.js$/));

참고 : ./js/의 하위 디렉터리에있는 .js 파일이 재귀 적으로 필요할 수 있습니다.

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