Webpack 从入口点开始处理您在应用程序中使用的每个模块,包括您导入的每个模块(import
or require
)并将其包含在您的捆绑包中。这__non_webpack_require__
是一个函数,它将产生一个简单的结果require
call.
我们以这个入口点为例:
const processedByWebpack = require("./module");
const notProcessed = __non_webpack_require__("./non-webpack");
console.log(processedByWebpack);
console.log(notProcessed);
在这种情况下,webpack 将捆绑该应用程序并包含您导入的每个模块,在这种情况下只是./module.js
。所以输出将是:
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
const processedByWebpack = __webpack_require__(1);
const notProcessed = require("./non-webpack");
console.log(processedByWebpack);
console.log(notProcessed);
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = "This module is bundled with webpack"
/***/ })
/******/ ]);
The ./module.js
模块包含在捆绑包中,并且如果存在任何适用的规则,也将由任何加载器处理。另一方面,./non-webpack.js
不包含在捆绑包中,并且 webpack 调用了require
。这意味着./non-webpack.js
将在执行时解决,如果它不可用或包含无效的 JavaScript,它将失败并出现运行时错误。
__non_webpack_require__
是一种解决 webpack 处理所有问题的方法require
来电。因为 webpack 捆绑了所有模块,所以它必须在编译时知道要包含哪些模块。这使得require
比 Node.js 中的实际限制更严格。例如,您不能使用动态require
s,这意味着您不能使用变量作为模块的路径(另请参阅webpack 通过 require 动态模块加载器 https://stackoverflow.com/questions/42797313/webpack-dynamic-module-loader-by-require)。例如:
// Path to module as a variable (could be an argument to a function)
const modulePath = "./module";
const processedByWebpack = require(modulePath); // Fails
const notProcessed = __non_webpack_require__(modulePath);
在常规的require
webpack 会失败,因为它不知道要包含哪些模块来覆盖运行时可以引用的所有模块。在此示例中,这似乎很明显,但它甚至可以使用用户输入来确定要加载的模块。和__non_webpack_require__
它只是创建一个require
打电话,你将不得不处理可能的情况Module not found
运行时异常。
你什么时候应该使用它?
可能永远不会。这是这些功能之一,应该被视为最后的手段,您需要避开 webpack 以获得一些动态模块解析。在大多数情况下,还有其他解决方案可以实现相同的目标(例如,通过使用将导入推迟到运行时)外部 https://webpack.js.org/configuration/externals/),其他一切都是边缘情况。
你会注意到__non_webpack_require__
被转化为require
称呼。这意味着它只能在 Node.js 中工作,并且在任何浏览器环境中都会失败,除非你有一个全局的require
定义可能会或可能不会做一些特殊的事情。另一个缺点是它是特定于 webpack 的,当你想使用另一个工具(例如用于测试)时,它不起作用,或者你将很难尝试解决它。