webpack动态模块加载器由require

Joh*_*ohn 10 javascript require node.js webpack webpack-2

好吧,我已经搜索过高低,但如果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"
    }
};
Run Code Online (Sandbox Code Playgroud)

server.js

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

require( 'modules/test' )();

_.map( modules, function( module ){
    require( module );
});
Run Code Online (Sandbox Code Playgroud)

模块中的模块/命名为test.js

module.exports = () => {
    console.log('hello world');
};
Run Code Online (Sandbox Code Playgroud)

但是结果总是一样的...pm2日志在1H41 for hello world for static require ...但是对于同一模块的动态加载

错误:找不到模块"."

我想要做的就是遍历模块的路径数组然后加载......

Mic*_*ngo 37

您不能将变量用作参数require.Webpack需要知道在编译时要捆绑哪些文件.由于它没有程序流分析,因此无法知道您传递给函数的内容.在这种情况下,它可能是显而易见的,但这可以使用用户输入来决定需要什么模块,并且webpack无法在编译时知道要包含哪些模块,因此webpack不允许它.

您发布的示例有点不同.您可以使用require连接字符串.例如:

require(`./src/${moduleName}/test`);
Run Code Online (Sandbox Code Playgroud)

webpack需要包含哪些模块?变量moduleName可以是任何东西,因此在编译时不知道确切的模块.相反,它包括可能与上述表达式匹配的所有模块.假设以下目录结构:

src
?? one
?   ?? test.js
?? two
?   ?? subdir
?   ?   ?? test.js
?   ?? test.js
?? three
    ?? test.js
Run Code Online (Sandbox Code Playgroud)

所有这些test.js文件都将包含在捆绑包中,因为它moduleName可能是one嵌套的东西two/subdir.

有关更多详细信息,请参阅require以及官方文档的表达.

您不能循环遍历数组并导入数组的每个模块,通过连接字符串具有上述异常,但这具有包括所有可能模块的效果,并且通常应该避免.

  • 如果只是在Webpack文档中清楚地解释了这些内容. (8认同)
  • 非常感谢您,我很感谢您澄清这一点,特别是对根本原因的详细描述。对于我应该如何加载我的文件以按照一般做法进行显示,您有什么建议吗?我对 React 编程和任何严肃的编程都很陌生,所以对什么样的设计模式合适的粗略想法会很棒,所以我可以进一步研究它们。谢谢。 (2认同)

Jos*_*ell 7

我在电子环境中遇到了这个问题。我的用例是能够require在类似IDE的应用程序中动态创建文件。我想使用电子元件require,它基本上是NodeJS Common模块加载器。经过一番往复后,我找到了一个使用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
Run Code Online (Sandbox Code Playgroud)

在我的webpack配置中的下module,指示捆绑程序不要解析此模块:

{
  module: {
    noParse: /\/native-require.js$/,
  }
}
Run Code Online (Sandbox Code Playgroud)

最后,在您要访问原始文件的任何捆绑包中,要求:

import nativeRequire from './native-require`
const someModule = nativeRequire('/some/module.js') // dynamic imports
Run Code Online (Sandbox Code Playgroud)


Gob*_*bot 5

有点晚了......但是......因为你捆绑到target: 'node',有一个动态需要模块的解决方法,并绕过 “包括所有可能模块的影响”

解决方案来自:

在不解析或捆绑目标模块的情况下对节点目标使用动态 require · 问题 #4175 · webpack/webpack

引自那条评论:

const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const foo = requireFunc(moduleName);
Run Code Online (Sandbox Code Playgroud)

捆绑到:

const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);
Run Code Online (Sandbox Code Playgroud)