從babel-polyfill的一個坑而起


從babel-polyfill的一個坑而起

babel-polyfill

Posted by Seize on January 6, 2018

問題

接手的系統幾天前出現了兼容性問題,Array.flat is not a function,一看原來是沒有引用babel-polyfill,直接import了babel-polyfill,發現並沒有解決問題。

原因

跑去看了一下babel-polyfill的git

@babel/polyfill IS just the import of stable core-js features and regenerator-runtime

This will emulate a full ES2015+ environment (no < Stage 4 proposals)

所以,babel-polyfill只是包括了穩定的corejs(小於stage 4的沒有)和regerator-runtime(這個是用來實現generator的)。

import "./noConflict"; import global from "core-js/library/fn/global" 

noConflict:

// Cover all standardized ES6 APIs. import "core-js/es6"; // Standard now import "core-js/fn/array/includes"; import "core-js/fn/array/flat-map"; import "core-js/fn/string/pad-start"; import "core-js/fn/string/pad-end"; import "core-js/fn/string/trim-start"; import "core-js/fn/string/trim-end"; import "core-js/fn/symbol/async-iterator"; import "core-js/fn/object/get-own-property-descriptors"; import "core-js/fn/object/values"; import "core-js/fn/object/entries"; import "core-js/fn/promise/finally"; // Ensure that we polyfill ES6 compat for anything web-related, if it exists. import "core-js/web"; import "regenerator-runtime/runtime"; 

ok,先去看一下core-js是什么:模塊化的標准庫,可提供所有es5 es6 es7的新特性,可以全局污染使用或者避免污染使用。第一個core-js/es6 里面包括了

這些對象擴展,點開Array

ok,whatever,flat是超綱了。(因為這里面是es6)

然后還有一個corejs/web,他用來兼容瀏覽器宿主對象,定時器等。

global是global對象。

看他后面那幾行又補充了一些新增的state4屬性

array新加includes和flatmap,what??

這里重點來了:為什么有flatmap,沒有flat???

So es2015+ 的state4 到底有啥?

先看一下什么是ECMA-262、ECMAScript

ECMA-262和ECMAScript

首先解釋一下ECMA(European Computer Manufactures Association)歐洲計算機制造商協會。 TC39(Technical Committee #39)39號技術委員會

  1. TC93制定了ECMA-262標准。

  2. ECMA-262是ECMAScript的標准,ECMA-262定義了ECMAScript。

  3. 由ECMA-262定義的ECMAScript與web服務器沒有依賴關系。ECMA-262定義的只是ECMAScript的語言基礎。我們常見的web瀏覽器只是ECMAScript實現可能的宿主環境之一。宿主環境不僅提供基本的ECMAScript實現,同時也會提供該語言的擴展,以便語言與環境之間對接交互。

  4. javascript實現了ECMAScript。

  5. 盡管 ECMAScript 是一個重要的標准,但它並不是 JavaScript 唯一的部分,當然,也不是唯一被標准化的部分。實際上,一個完整的 JavaScript 實現是由以下 3 個不同部分組成的:
    1. 核心(ECMAScript) 2. 文檔對象模型(DOM) 3. 瀏覽器對象模型(BOM)

ES2015

ECMAScript 2015 is an ECMAScript standard that was ratified in June 2015.

2015年六月獲得批准的。

完整版鏈接

es6新增:

所以es2015也不多,array就加了from、of等5個,也沒有flatMap,那為什么polyfill里面加了它呢,而不加flat呢?

我們用的是babel 7.4,babel 7是core-js@2

Right now @babel/polyfill is mostly just an alias of core-js v2. Source

babel 6時代,babel/polyfill包括所有state,它這么引:

import "core-js/shim"; // included < Stage 4 proposals import "regenerator-runtime/runtime"; 

core-js/shim的文檔:

Below is a list of Stage < 3 proposal polyfills in core-js v2.

// core-js v2 // Stage 3 import "core-js/fn/string/trim-left"; import "core-js/fn/string/trim-right"; import "core-js/fn/string/match-all"; import "core-js/fn/array/flat-map"; import "core-js/fn/array/flatten"; // RENAMED import "core-js/fn/global"; // Stage 1 import "core-js/fn/symbol/observable"; import "core-js/fn/promise/try"; import "core-js/fn/observable"; // Stage 1 Math Extensions import "core-js/fn/math/clamp"; import "core-js/fn/math/deg-per-rad"; import "core-js/fn/math/degrees"; import "core-js/fn/math/fscale"; import "core-js/fn/math/iaddh"; import "core-js/fn/math/isubh"; import "core-js/fn/math/imulh"; import "core-js/fn/math/rad-per-deg"; import "core-js/fn/math/radians"; import "core-js/fn/math/scale"; import "core-js/fn/math/umulh"; import "core-js/fn/math/signbit"; // Stage 1 "of and from on collection constructors" import "core-js/fn/map/of"; import "core-js/fn/set/of"; import "core-js/fn/weak-map/of"; import "core-js/fn/weak-set/of"; import "core-js/fn/map/from"; import "core-js/fn/set/from"; import "core-js/fn/weak-map/from"; import "core-js/fn/weak-set/from"; // Stage 0 import "core-js/fn/string/at"; // Nonstandard import "core-js/fn/object/define-getter"; import "core-js/fn/object/define-setter"; import "core-js/fn/object/lookup-getter"; import "core-js/fn/object/lookup-setter"; // import "core-js/fn/map/to-json"; // Not available standalone // import "core-js/fn/set/to-json"; // Not available standalone import "core-js/fn/system/global"; import "core-js/fn/error/is-error"; import "core-js/fn/asap"; // Decorator metadata? Not sure of stage/proposal import "core-js/fn/reflect/define-metadata"; import "core-js/fn/reflect/delete-metadata"; import "core-js/fn/reflect/get-metadata"; import "core-js/fn/reflect/get-metadata-keys"; import "core-js/fn/reflect/get-own-metadata"; import "core-js/fn/reflect/get-own-metadata-keys"; import "core-js/fn/reflect/has-metadata"; import "core-js/fn/reflect/has-own-metadata"; import "core-js/fn/reflect/metadata"; 

Core-js @2的時候flat和flatmap都是state3,然而我又去看了tc39 esma 262的git

Soga,這幾個state3 現在已經是state4了,

所以babel/polyfill補充了這些:

說明緊跟state4走,沒問題。

我們的問題還沒解決,那為什么沒有flat,只有flat-map。

這又是另一個故事了

what is wrong with flat ?

flat原來名叫flatten,和國外一個叫Mootools的框架命名沖突了。造成了smooshGate,smoosh門事件

咋回事呢?

Mootools框架定義了自己的Array.prototype.flatten 與標准不同,並且會覆蓋原生實現,這雖然會導致新的網站同時使用這兩者會出問題,但不會導致之前的網站出問題。但是,mootools還會把自定義的方法復制到他自己的一個api對象Element:

for(var key in Array.prototype){ Element.prototype[key] = Array.prototype[key] } 

本來Element能得到flatten,因為它是自己定義的屬性,可以被for in枚舉。但是flatten被標准實現之后,變成不可枚舉了,所有使用Element.prototype.flatten的代碼就完犢子了。

作者開了個玩笑,不如把flatten改成smooth,造成了更大的影響。。。

18年3月 TC39開會討論這一問題

18年5月 TC39開會再討論:

not smoosh~ be serious~

所以啊,歸根結底竟然是一個名字造成的鍋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM