导入的变量有效但在调试器中访问时未定义(在相同的范围内)

min*_*eow 9 javascript ecmascript-6 es6-module-loader

我使用webpack + es6来构建我的文件.我在Math.js中导出模块,然后在Main.js中导入.

在后者中,我使用模块进行计算,然后在调试器中设置停止.前者工作但当我尝试在控制台中使用它时没有定义.

范围是相同的 - 为什么模块不在控制台中定义?

// Math.js
export function sum(x, y) {
  return x + y;
}
export var pi = 3.141593;

// Main.js
import * as mathTest from "./Math.js";
console.log("2? = " + mathTest.sum(mathTest.pi, mathTest.pi));
debugger

// Output
// The statement from the file writes properly but the debugger fails (but <this> is the same)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

hen*_*enk 2

尽管手术可能会迟到,但这仍然是一个有效的问题。

虽然看起来您正在调试自己编写的代码,但事实并非如此。

原因是你的代码被 webpack 缩小和丑化了(并且可能被 babel 转译)。编译后的代码由浏览器执行,然后浏览器通过源映射将其映射到源代码。

浏览器尽最大努力让这种体验尽可能无缝。在大多数情况下,您甚至不会注意到这种错觉,但在其他情况下,它可能会让您感到困惑。由于变量和模块导入在丑化过程中被重命名,因此它们在控制台中不再以其原始名称可用。

因此,为了找出导入模块的值,您必须观察编译的变量。

截至 2021 年,您可以从浏览器中获得为此目的提供的大力帮助。如下图所示, while Thingwill be会给您预期的结果,甚至是自动补全建议的undefined_Thing

另外,请注意 in [sm]App.js[sm]它表示您正在观察源映射版本而不是执行的代码。

源地图的可视化

或者,我们可以观察编译/执行的代码,并验证是否Thing导入为_Thing.

编译代码的可视化

相关且经常遇到的问题:

  • 调试器无法在所需的断点处停止。
  • 调试器中不可用于断点的行。
  • 控制台错误指向丑陋的代码。

如果您想了解原因,请深入研究源映射: 源映射如何工作?