webpack 动态模块加载器通过 require
webpack dynamic module loader by require
好吧,我搜索了高低,但无法可靠地确定 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 );
});
modules/ 中的模块名为 test.js
module.exports = () => {
console.log('hello world');
};
但结果总是一样的...pm2 日志只是针对静态需求说 hello world...但针对同一模块的动态负载
Error: Cannot find module "."
我想做的就是遍历模块路径数组然后加载...
您不能将变量用作 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
所有这些 test.js
文件都将包含在捆绑包中,因为 moduleName
可能是 one
或类似 two/subdir
.
的嵌套文件
有关更多详细信息,请参阅官方文档的 require with expression。
您不能遍历数组并导入数组的每个模块,除了上述通过连接字符串的例外情况,但这会产生包含所有可能模块的效果,通常应避免。
有点晚了....但是...因为您要捆绑到 target: 'node'
,所以有一个动态需要模块的解决方法,并绕过 "the effect of including all possible modules".
解决方案摘自:
引自该评论:
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const foo = requireFunc(moduleName);
捆绑到:
const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);
我运行在电子环境下解决这个问题。我的用例是能够 require
在类似 IDE 的应用程序中动态创建文件。我想使用 electron require
,它基本上是一个 NodeJS 通用模块加载器。经过一些来回,我找到了一个使用 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
好吧,我搜索了高低,但无法可靠地确定 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 );
});
modules/ 中的模块名为 test.js
module.exports = () => {
console.log('hello world');
};
但结果总是一样的...pm2 日志只是针对静态需求说 hello world...但针对同一模块的动态负载
Error: Cannot find module "."
我想做的就是遍历模块路径数组然后加载...
您不能将变量用作 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
所有这些 test.js
文件都将包含在捆绑包中,因为 moduleName
可能是 one
或类似 two/subdir
.
有关更多详细信息,请参阅官方文档的 require with expression。
您不能遍历数组并导入数组的每个模块,除了上述通过连接字符串的例外情况,但这会产生包含所有可能模块的效果,通常应避免。
有点晚了....但是...因为您要捆绑到 target: 'node'
,所以有一个动态需要模块的解决方法,并绕过 "the effect of including all possible modules".
解决方案摘自:
引自该评论:
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const foo = requireFunc(moduleName);
捆绑到:
const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);
我运行在电子环境下解决这个问题。我的用例是能够 require
在类似 IDE 的应用程序中动态创建文件。我想使用 electron require
,它基本上是一个 NodeJS 通用模块加载器。经过一些来回,我找到了一个使用 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