首页 > 解决方案 > 为什么 Webpack 会将作为 ES 模块导入的函数传递给 Webpack 4 中的 Object 调用?

问题描述

这是一些人为的代码:

// index.js
import { log } from './log';

log('hello world');

// log.js
export const log = string => console.log(string);

在没有配置的情况下构建它会产生以下字符串化源:

"__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log */ \"./src/log.js\");\n\n\nObject(_log__WEBPACK_IMPORTED_MODULE_0__[\"log\"])('hello world');\n\n//# sourceURL=webpack:///./src/index.js?")

我感兴趣的一点是:

"Object(_log__WEBPACK_IMPORTED_MODULE_0__[\"log\"])('hello world');"

我一生都无法弄清楚为什么将日志函数传递给Object调用。我已经查看了引入 this 的提交,但是尝试将带有上下文的函数传递到该调用中似乎并没有解除它们的绑定——它只会按原样返回引用。

非常感谢任何帮助找出为什么存在的帮助。

标签: webpack

解决方案


将导出包装在对 Object 构造函数的调用中的原因是将导出作为普通函数调用,而不是 Webpack 导出对象上的方法。

当涉及到 ES6 模块时,Webpack 并没有严格实现规范,而是通过将导出转换为 Webpack 导出对象上的属性来简化事情,而不是静态绑定。当一个函数被添加到 JavaScript 中的一个对象时,它就变成了一个“方法”,并在将该函数作为方法调用时this引用它定义的对象。

在您的示例中,Webpack 避免将您的模块导出作为导出对象上的方法调用。

_log__WEBPACK_IMPORTED_MODULE_0__[\"log\"]('hello world')  // WRONG invoking `log` as a method

对比

Object(_log__WEBPACK_IMPORTED_MODULE_0__[\"log\"])('hello world')  // RIGHT invoking `log` as a function

他们以一种巧妙的方式使用 Object 构造函数,因为它只会返回传递给它的任何未修改的函数。他们可以通过使用额外的变量赋值来完成同样的事情。

const temp = _log__WEBPACK_IMPORTED_MODULE_0__[\"log\"]
temp('hello world')

请参阅此处this处理ES6 模块绑定的 Webpack 测试以及有关导出箭头函数的违反 ES6 模块规范的问题。

另请参阅文档,this其中应undefined在 ES6 模块范围内,因为模块始终处于严格模式,其中this函数体中的undefined不是window或对导出对象的引用。


推荐阅读