Babel ES6 模块:为什么 Babel 会重命名导入?

3
当我在ES6导入上运行babel时,它会一直重命名我的导入,直到我的源代码中:
import {foo as bar} from './bar';
console.log(bar);

变得

'use strict';
var _bar = require('./bar');
console.log(_bar.foo);

一个命名导入是通过重命名来实现的:
import {bar} from './bar';
console.log(bar);

为了

'use strict';
var _bar = require('./bar');
console.log(_bar.bar);

对于默认导入,情况甚至更糟,因为会多添加一个2:

import bar from './bar';
console.log(bar);

成为

'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _bar = require('./bar');
var _bar2 = _interopRequireDefault(_bar);
console.log(_bar2['default']);

为什么babel会这样做?背景:在Chrome中调试应用程序时,我需要转到源文件以查找变量如何被重命名以获取其当前值,因为Chrome不知道bar已被重命名为_bar.bar… 这使得使用WebStorm等工具进行调试几乎不可能…
为什么babel不能将命名导入转换为
'use strict';
var _bar = require('./bar');
var bar = _bar.bar;
console.log(bar);

默认导入到

'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _bar = require('./bar');
var _bar2 = _interopRequireDefault(_bar);
var bar = _bar2['default']
console.log(bar);

1
我无法回答“为什么”,但是你应该生成sourcemaps以便调试,否则你将会遇到更难的问题来调试,而不是找到模块的名称。 - CodingIntrigue
我正在生成源映射,但据我所知,Chrome Inspector不知道源映射并且无法检测变量重命名...此外,调试器会“跳转”到正确的源文件,但无法检查变量。 - david
2
“为什么Babel不能转换……” - 它肯定可以,只是他们没有这样做。我认为除了可调试性之外,选择其中一个而不是另一个没有任何好的理由,因为它们被等效地评估。如果您关心此事,您可能需要打开一个错误报告(功能请求?)。 - Bergi
1个回答

5
那是为了模拟模块导入的“引用”本质。
import {foo as bar} from './bar';
console.log(bar);

bar 不仅仅是一个保存值的变量,它是从另一个模块导出的一个 引用。如果导出的值发生变化,导入的值也会随之改变。

例如:

// a.js
export var a = 42;
setTimeout(() => a = 21, 500);

// b.js
import {a} from './a';
setTimeout(() => console.log(a), 1000);

根据规范,b.js中的代码必须记录21。由于JavaScript没有 按引用赋值 ,实现这种行为的唯一方法是将每个导入都转换为MemberExpression (foo.bar)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接