有没有办法从Babel获得更小的代码?

时间:2017-01-28 10:07:19

标签: ecmascript-6 babeljs

在这种情况下,我发现一些不太理想的代码生成:

const selectedReddit = (state = 'reactjs', action) => {
  console.log(state, action);
}

变成了这个:

'use strict';
var selectedReddit = function selectedReddit() {
  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'reactjs';
  var action = arguments[1];

  console.log(state, action);
};

这可能是一个相当大的代码膨胀:

'use strict';
function selectedReddit(state, action) {
  state = state || 'reactjs';

  console.log(state, action);
};

也许这与let的转换有关,但这似乎是默认参数的相当昂贵的转换。是否有一些代码缩小可以应用于此输出,或者是一个可以产生更小代码的不同变换器?

需要119时使用219个字符。这大约是45%的代码膨胀。

Playground example

@lonesomeday指出这不适用于state === false

'use strict';
function selectedReddit(state, action) {
  state = (state === undefined) ? 'reactjs' : state;

  console.log(state, action);
};

其中重量为160字节,这只是26%的代码膨胀。

我不确定为什么var funcName = function funcName会被插入以及为什么所有参数都成为参数[index]。

在ES6中写作会很棒,但是这几乎让人感到尖叫!如果你的代码将以这种方式为浏览器编译。

1 个答案:

答案 0 :(得分:0)

还有一些事情正在发生。请注意,这些都是由您提出的建议与Babel生成的内容之间的某些实际行为差异(这与规范要求的内容非常匹配)所支持的信息推测;我不知道实际的动机。

  • var f = function f(){}代替function f(){}的原因是它避免了hoisting。这不重要,但是例如console.log(f); var f = function f(a) { return a; };console.log(f); function f(a) { return a; }不同:第一个会打印undefined,第二个会打印该功能。

  • 它需要在表达式中包含函数的名称,因为它会影响ES6之前环境中函数的.name属性(在函数名称推断之前)。在ES6环境中,const f = a => a; console.log(f.name);将打印'f';在ES6之前的环境中,var f = function(a) { return a; }; console.log(f.name);将打印''

  • 大概它使用arguments而不是命名形式参数的原因是它影响函数的.length属性:((a = 0, b) => {}).length === 0,而(function f(a, b){...}).length === 2。< / p>

  • 正如评论中所指出的,state || 'reactjs'会在指定任何虚假值时向您reactjs提供,而不仅仅是undefined

  • 如果有人在arguments.length上定义0属性,则需要进行Object.prototype检查:Object.prototype[0] = 'evil'; (function f(){return arguments[0] !== 'undefined' ? arguments[0] : 'default'; })()将返回'evil'而不是{{1} }}

Babel历史上在6到5天内生成的代码更接近您所写的代码。事实证明,生成代码的编译器只是 在语义上与你编写的代码相同是一个非常痛苦的编译器。

至于您的实际问题,Babel有'default'预设,但它不会影响您编写的代码。总的来说,生成正确的代码的价值通常会超过生成更短代码的价值。