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

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

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

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

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

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

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



답변

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

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


답변

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

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

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

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


답변

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

// { 
//   './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, /.*/));


답변

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

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


답변

@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'
    }
  }
}


답변

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

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

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

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


답변