web-dev-qa-db-ja.com

requireによるwebpack動的モジュールローダー

わかりました、私は高低を検索しましたが、これがwebpackで可能か不可能かを確実に判断することはできません。

https://github.com/webpack/webpack/tree/master/examples/require.context 文字列を関数に渡し、モジュールをロードできることを示すように表示されます...

しかし、私の試みはうまくいきません:webpack.config.js

'use strict';
let webpack     = require('webpack'),
    jsonLoader  = require("json-loader"),
    path        = require("path"),
    fs          = require('fs'),
    nodeModules = {};

fs.readdirSync('node_modules')
    .filter(function(x) {
        return ['.bin'].indexOf(x) === -1;
    })
    .forEach(function(mod) {
        nodeModules[mod] = 'commonjs ' + mod;
    });


let PATHS = {
    app: __dirname + '/src'
};

module.exports = {
    context: PATHS.app,
    entry: {
        app: PATHS.app+'/server.js'
    },
    target: 'node',
    output: {
        path: PATHS.app,
        filename: '../build/server.js'
    },
    externals: nodeModules,
    performance: {
        hints: "warning"
    },
    plugins: [
        jsonLoader
    ],
    resolve: {
        modules: [
            './node_modules',
            path.resolve(__dirname),
            path.resolve(__dirname + "/src"),
            path.resolve('./config')
        ]
    },
    node: {
        fs: "empty"
    }
};

Server.js

let _ = require('lodash');
let modules = [ "modules/test" ];

require( 'modules/test' )();

_.map( modules, function( module ){
    require( module );
});

モジュール内のモジュール/ test.jsという名前

module.exports = () => {
    console.log('hello world');
};

しかし、結果は常に同じです... pm2のログでは、静的なrequireに対してhello worldと言うだけですが、同じモジュールの動的な負荷に対してです。

エラー:モジュール "。"が見つかりません

私ができることはすべて、モジュールへのパスの配列をループしてロードすることです...

11
John

requireの引数として変数を使用することはできません。 Webpackは、コンパイル時にバンドルするファイルを知る必要があります。プログラムフロー分析を行わないため、関数に何を渡すかを知ることはできません。その場合は明白かもしれませんが、これはユーザー入力を使用して必要なモジュールを決定するまで及ぶ可能性があり、webpackがコンパイル時に含めるモジュールを認識できない可能性があるため、webpackはそれを許可しません。

投稿した例は少し異なります。 requireを連結文字列と一緒に使用できます。例えば:

require(`./src/${moduleName}/test`);

バンドルにwebpackを含める必要があるのはどのモジュールですか?変数moduleNameは何でもかまいませんので、正確なモジュールはコンパイル時にはわかりません。代わりに、上記の式に一致する可能性のあるallモジュールが含まれています。次のディレクトリ構造を想定します。

src
├─ one
│   └─ test.js
├─ two
│   ├─ subdir
│   │   └─ test.js
│   └─ test.js
└─ three
    └─ test.js

moduleNameoneまたはtest.jsのようにネストされているため、これらのすべてのtwo/subdirファイルがバンドルに含まれます。

詳細については、公式ドキュメントの 式で必須 を参照してください。

配列をループして配列のすべてのモジュールをインポートすることはできません。ただし、上記の例外を除いて、文字列を連結することはできますが、これにはすべての可能なモジュールが含まれるため、通常は避けてください。

34
Michael Jungo

私は電子環境でこの問題に遭遇しました。私のユースケースは、IDEアプリケーションのように動的に作成されたファイルをrequireできました。基本的にNodeJS Commonである電子requireを使用したかったモジュールローダー。前後して、webpackのnoParseモジュール構成を使用するソリューションにたどり着きました。

最初に、webpackのパーサーによって無視されるモジュールを作成します。

// file: native-require.js
// webpack replaces calls to `require()` from within a bundle. This module
// is not parsed by webpack and exports the real `require`
// NOTE: since the module is unparsed, do not use es6 exports
module.exports = require

私のwebpack設定のmoduleで、このモジュールを解析しないようにバンドラーに指示します。

{
  module: {
    noParse: /\/native-require.js$/,
  }
}

最後に、元のパッケージにアクセスするバンドルでは、次のものが必要です。

import nativeRequire from './native-require`
const someModule = nativeRequire('/some/module.js') // dynamic imports
7
Josiah Ruddell

少し遅い....しかし... target: 'node'にバンドルしているので、動的な必須モジュールに回避策があり、 "可能なすべてを含めることの影響をバイパスしますモジュール "

ソリューションは以下から引き上げられます:

ターゲットモジュールを解決またはバンドルせずにノードターゲットで動的なrequireを使用・問題#4175・webpack/webpack

そのコメントから引用:

const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const foo = requireFunc(moduleName);

バンドル:

const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);
2
Gobot