requireステートメントなしでwebpackを使用してディレクトリ内のすべてのファイルをロードする方法


95

アプリの4つのサブディレクトリに分割された大量のJavaScriptファイルがあります。うなり声で私はそれらすべてを取得し、1つのファイルにコンパイルします。これらのファイルにはmodule.exports関数がありません。

Webpackを使用して4つの部分に分割したいと思います。手動で行ってすべてのファイルを要求したくありません。

コンパイル時にディレクトリツリーをウォークし、すべての.jsファイル名とパスを取得し、サブディレクトリ内のすべてのファイルを要求して、それを出力に追加するプラグインを作成したいと思います。

各ディレクトリのすべてのファイルをモジュールにコンパイルして、エントリポイントファイルから必要とするか、http: //webpack.github.io/docs/plugins.htmlで言及されているアセットに含めることができます。

新しいファイルを追加するときは、正しいディレクトリにドロップして、それが含まれることを確認したいだけです。

これを行うために誰かが作成したwebpackまたはプラグインでこれを行う方法はありますか?

回答:


119

これは私がこれを達成するためにしたことです:

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

使用するローダーを指定する方法はありますか?私のユースケースでは、image-size-loader正しいアスペクト比のプレースホルダーを作成するために、すべての画像にを使用したいと考えています。
ボバルバ2015年

13
作業サンプルwebpack.config.jsを提供していただけませんか
Rizwan Patel

2
@bobbaluba、構成ファイルでローダーを指定できます:loaders: [ { test: /\.json$/, loader: 'json' } ]{ test: /\.json$/, loader: 'json' }ローダーがインストールされている限り、.jsonファイルのjsonローダーを追加します。
ジェイク

1
ここrequire.context(...)であなたを呼び出す関数を記述してDRYにしようとすると(たとえば、すべてのフォルダーにすべてを要求しようとすると)、webpackが警告をスローすることに注意してください。引数require.contextはコンパイル時の定数でなければなりません。
アイザックライマン

3
@Joel npmjs.com/package/require-contextは2017年に作成され、私の回答は2015年からのものであるため、そこから直接取得したとは言いがたいです。また、require-contextはラッパーwebpackであり、そのサンプルはwebpackwebpack.js.org / guides / dependency - management /#context - module - apiのドキュメントから取得されたものです(2016年に追加されました(github.com/webpack/にあります)。 webpack.js.org/commit/…)、私が回答を書き込んだ後も...多分、webpackのライターは私の回答に影響されたのでしょう。キャッシュを持つように拡張したことに注意してください。
破片

38

私のアプリファイルには、必要なものを入れてしまいました

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

この投稿の礼儀:https : //github.com/webpack/webpack/issues/118

これですべてのファイルが追加されます。私はhtmlとcssのローダーを持っています。


27
exprこの例には何がありますか?
twiz 2015

2
exprコンテキストフォルダー内の単一ファイルへのパスです。したがって、すべてのhtmlファイルを要求するためだけでなく、これを行う必要がある場合、これは便利です。webpack.github.io/docs/context.html#context-module-api
mkoryak

18
exprWebpackのドキュメントを見た後でも、ベースの引数がここで何をしているのかはまだはっきりしていません。「これはすべてのhtmlファイルを要求するためだけではない」とはどういう意味ですか?ありがとう
mikkelrd、2015年

3
私が持って定義されていない式expr:キャッチされないにReferenceErrorを。それについて何かヒントはありますか?
CSchulz

2
exprここで何を意味するのかについてはまだ回答がありません
ウィズルス2018

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

この例を削除していただきありがとうございます。私はマップを使用して、各ファイルがエクスポートした値を返します=)。
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は、そのファイル名から作成されます。
    • ...拡張子なしで、スラッシュをアンダースコアに置き換えます(サブディレクトリスキャンの場合)。
  • カスタマイズを容易にするためにコメントを追加しました。
    • つまり、ルートレベルのモジュールに手動で必要なファイルがある場合などは、サブディレクトリにファイルを含めないようにすることができます。

編集:私のように、モジュールが通常のjavascriptオブジェクト(少なくともルートレベル)以外のものを返さないと確信している場合は、元のディレクトリ構造を複製して「マウント」することもできます(コード(ディープバージョン)最後のセクション)。

コード(オリジナルバージョン):

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.