b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

不同浏览器兼容性问题 你的Tree-Shaking并没什么卵用(3)

电脑杂谈  发布时间:2018-01-11 13:08:04  来源:网络整理

假如是我的话,我可能会这样去编译:

var Person = function () {
  function Person() {

  }
  Person.prototype.getName = function () { return this.name };
  return Person;
}();

因为我们以前就是这么写“类”的,那babel为什么要采用 Object.defineProperty这样的形式呢,用原型链有什么不妥呢?自然是非常的不妥的,因为ES6的一些语法是有其特定的语义的。比如:

类内部声明的方法,是不可枚举的,而通过原型链声明的方法是可以枚举的。这里可以参考下阮老师介绍

for...of的循环是通过遍历器(Iterator)迭代的,循环数组时并非是i++,然后通过下标寻值。这里依旧可以看下阮老师关于遍历器与for...of的介绍,以及一篇babel关于for...of编译的说明transform-es2015-for-of

所以,babel为了符合ES6真正的语义,编译类时采取了 Object.defineProperty来定义原型方法,于是导致了后续这些一系列问题。

眼尖的同学可能在我上述第二点中发的链接 transform-es2015-for-of中看到,babel其实是有一个 loose模式的,直译的话叫做宽松模式。它是做什么用的呢?它会不严格遵循ES6的语义,而采取更符合我们平常编写代码时的习惯去编译代码。比如上述的 Person类的属性方法将会编译成直接在原型链上声明方法。

这个模式具体的babel配置如下:

不同浏览器兼容性问题_浏览器兼容性问题总结_360浏览器兼容性问题

// .babelrc
{
  "presets": [["env", { "loose": false }]]
}

同样的,我放个repl示例方便大家直接查看效果:

咦,如果我们真的不关心类方法能否被枚举,开启了 loose模式,这样是不是就没有副作用产生,就能完美tree-shaking类了呢?

我们开启了 loose模式,使用rollup打包,发现还真是如此! 传送门

然而不要开心的太早,当我们用Webpack配合UglifyJS打包文件时,这个Person类的IIFE又被打包进去了? What???

为了彻底搞明白这个问题,我搜到一条UglifyJS的issue: Class declaration in IIFE considered as side effect,仔细看了好久。对此有兴趣、并且英语还ok的同学,可以快速去了解这条issue,还是挺有意思的。我大致阐述下这条issue下都说了些啥。

issue楼主- blacksonic

好奇为什么UglifyJS不能消除未引用的类。

UglifyJS贡献者-kzc说,uglify不进行程序流分析,所以不能排除有可能有副作用的代码。

楼主:我的代码没什么副作用啊。要不你们来个配置项,设置后,可以认为它是没有副作用的,然后放心的删了它们吧。

贡献者:我们没有程序流分析,我们干不了这事儿,实在想删除他们,出门左转 rollup 吼吧,他们屌,做了程序流分析,能判断到底有没有副作用。

楼主:迁移rollup成本有点高啊。我觉得加个配置不难啊,比如这样这样,巴拉巴拉。

贡献者:欢迎提PR。

楼主:别嘛,你们项目上千行代码,我咋提PR啊。我的代码也没啥副作用啊,您能详细的说明下么?

贡献者:变量赋值就是有可能产生副作用的!我举个例子:


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-59797-3.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...