摘要:版本截圖當然,搜狗瀏覽器市場份額也不低,官方最新版本是,內核版本是,為之一驚。上面代碼的和分別是什么含義呢如果是下面的配置有何不可呢首先來明確一個概念是一系列的集合。比如做移動端開發不需要考慮之類的端產品線只考慮指定的瀏覽器等。
因babel的版本從5升級到6有很多改動,比如babel本身不再提供任何transform的工作,都需要借助插件來完成,本文的所有討論都是建立在babel 6之上的。如果只想看結論,直接跳到文章最后。 ---寫在前面
ES6即ECMAScript 6,是前端開發的JS最新規范,現在大家的開發都在使用ES6,對此并不陌生了。只是瀏覽器對ES6的支持并不完整,想要更好讓ES6在各個平臺完美運行還需一番折騰,特此一敘。下圖是ES6的瀏覽器兼容性一覽表(已ES6的Number為例):
另外國內瀏覽器都號稱是“雙核”,實際上瀏覽器的版本號較新,打包的Webkit內核確很低,比如市場份額很高的360安全瀏覽器,最新版本是9.1,Webkit內核版本才是55.0.2883,要知道Chrome官方最新版本已是62.0.3202,相差之遠不甚理解。
版本截圖:
userAgent:
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 QIHU 360SE"
當然,搜狗瀏覽器市場份額也不低,官方最新版本是7.1,內核版本是49.0.2623,為之一驚。
版本截圖:
userAgent:
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"
因此,我們想要在所有的瀏覽器上平穩、完美的運行ES6代碼,必須要了解它的忠實伴侶 Babel。
大家可能對此也并不陌生,但是對babel的內部機制、插件的作用、兼容的配置還缺乏一些認識,本文就是特意嘗試來補全這些內容。
使用babel無非要用到.babelrc文件或者在package.json增加babel字段。我們以.babelrc文件為例:
{ "presets":["es2015","stage-0"], "plugins": ["transform-runtime"] }
這是最常見的babel配置,然后結合webpack下的babel-loader完成對JS代碼的babel編譯。
上面代碼的presets和plugins分別是什么含義呢?如果是下面的配置有何不可呢?
{ "presets":["es2015","stage-0"] }
首先來明確一個概念: presets是一系列plugin的集合。比如上述配置中es2015表示babel-preset-es2015,它包含以下plugin:
check-es2015-constants
transform-es2015-arrow-functions
transform-es2015-block-scoped-functions
transform-es2015-block-scoping
transform-es2015-classes
transform-es2015-computed-properties
transform-es2015-destructuring
transform-es2015-duplicate-keys
transform-es2015-for-of
transform-es2015-function-name
transform-es2015-literals
transform-es2015-modules-commonjs
transform-es2015-object-super
transform-es2015-parameters
transform-es2015-shorthand-properties
transform-es2015-spread
transform-es2015-sticky-regex
transform-es2015-template-literals
transform-es2015-typeof-symbol
transform-es2015-unicode-regex
transform-regenerator
使用presets的好處就是不用再plugins配置里一個一個的寫了。
然后,我們通過對代碼的編譯來看下上面兩個配置的區別。源碼如下:
let a=1; let b=(item)=>{return item+1}; let c="1".padStart(2,"0"); let d=Object.assign({k:2},{t:4}); let e=new Set();
我們使用第二種配置,得到的編譯結果如下:
"use strict"; var a = 1; var b = function b(item) { return item + 1; }; var c = "1".padStart(2, "0"); var d = Object.assign({ k: 2 }, { t: 4 }); var e = new Set();
從編譯結果來看,let、箭頭函數都被編譯了,然而padStart和Object.assign原樣輸出了。原因很簡單,let被編譯是使用了es2015中的transform-es2015-block-scoping,箭頭函數編譯是使用了es2015的transform-es2015-arrow-functions。padStart、Object.assign和Set并未在es2015和state-0中找到對應plugin。我們再使用第一種配置編譯,結果如下:
"use strict"; var _set = require("babel-runtime/core-js/set"); var _set2 = _interopRequireDefault(_set); var _assign = require("babel-runtime/core-js/object/assign"); var _assign2 = _interopRequireDefault(_assign); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var a = 1; var b = function b(item) { return item + 1; }; var c = "1".padStart(2, "0"); var d = (0, _assign2.default)({ k: 2 }, { t: 4 }); var e = new _set2.default();
從編譯結果看,let、箭頭函數、Object.assign、Set都被正確編譯,padStart仍巋然不動。在這友情提醒一下,babel-plugin-transform-runtime是依賴babel-runtime的。那么如何讓padStart方法也能被成功編譯呢,這么大的開場白終于聊到了我們今天的主題:babel的polyfill方案。
官方推薦的方式是使用babel-polyfill。
This will emulate a full ES2015+ environment and is intended to be used in an application rather than a library/tool. This polyfill is automatically loaded when using babel-node.
This means you can use new built-ins like Promise or WeakMap, static methods like Array.from or Object.assign, instance methods like Array.prototype.includes, and generator functions (provided you use the regenerator plugin). The polyfill adds to the global scope as well as native prototypes like String in order to do this.
用最簡單的方式概括官方的說法就是:只要引入了babel-polyfill你可以大膽的用ES6。基本方法如下:
先安裝
npm install --save babel-polyfill
后使用
// 在代碼中顯示調用 require("babel-polyfill"); // or import "babel-polyfill";
或者在webpack中配置
module.exports = { entry: ["babel-polyfill", "./index.js"] };
那么問題來了,既然使用這么簡單,有啥弊端沒?這個問題的答案也很簡單:它無疑大大增加了代碼的體積,即使你只有1k的代碼,也會打包出幾百k出來。如果不在意這個代碼的體積,肆意大膽的去用吧。如果想做到代碼清爽、合理的利用babel的功能還請繼續閱讀。
使用babel-polyfill可以不使用presets和transform-runtime,但是不意味著presets和transform-runtime沒有用武之地。在此總結了幾個原則:
純業務開發
第一、先要考慮所有兼容的平臺和環境,選擇性的使用babel-polyfill和transform-runtime。
通常情況下業務代碼較重,再加上業務邏輯復雜的話,使用的ES6語法比較全面很頻繁,還要考慮到各個小伙伴的代碼兼容性,使用babel-polyfill結合webpack抽離出公共代碼庫,整體上還是能節省代碼體積的。如果想全盤使用babel-polyfill并且在此基礎上進行優化的話,請參考第二點。
第二、放棄使用preset-es2015、preset-state-0,請使用preset-env。
babel-polyfill的引入會自動加入很多代碼,有時候我們并不完全需要。比如:做移動端開發不需要考慮IE之類的、B端產品線只考慮指定的瀏覽器等。這個時候使用prest-env就可以了。配置如下:
{ "presets": [ ["env", { "targets": { "browsers": ["last 2 versions", "safari >= 7"] } }] ] }
browsers的可選值參考 browserslist;有幾個點要提醒一下:
上述的"last 2 versions"是主版本,這樣配置會引入很多代碼,建議針對性的配置。
雖然使用了preset-env會針對指定的平臺進行編譯代碼,但是要注意,即使你的代碼都是ES5,打包出來的體積也不會小,因為它不是根據你的代碼來選擇性的編譯,而是根據平臺。如果想進一步優化,如根據平臺也要根據代碼來選擇性的polyfill,請參考 @babel/preset-env
類庫和工具開發
第一、盡量避免使用babel-polyfill而使用tranform-runtime
If you are looking for something that won"t modify globals to be used in a tool/library, checkout the transform-runtime plugin. This means you won"t be able to use the instance methods mentioned above like Array.prototype.includes.
官方這句話換個角度講就是類庫的開發建議使用transform-runtime,它的原則是不改變原型鏈上的方法,但是通過babel-runtime或者core-js手動引入,這樣不僅代碼優雅編譯的包體積會小很多。
第二、選擇性的使用ES6語法
ES6雖然很強大,但是很多方法使用ES5仍可輕松實現。看下剛才提及的 Array.prototype.includes方法:
// ES6寫法 let a=[1,2,3]; if(a.includes(1)){ console.log("1 is finded"); }
// ES5寫法 let a=[1,2,3]; if(a.some((item)=>{return item===1})){ console.log("1 is finded"); }
這兩個寫法區別并不大,但是如果使用ES6的寫法再加上polyfill的引入,代碼要多不少。
兼容到IE8-
請老老實實使用babel-polyfill。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90263.html
摘要:年,很多人已經開始接觸環境,并且早已經用在了生產當中。我們發現,關鍵字會被編譯成構造函數,于是我們便可以通過來實現實例的生成。下一篇文章我會繼續介紹如何處理子類的并會通過一段函數橋梁,使得環境下也能夠繼承定義的。 2017年,很多人已經開始接觸ES6環境,并且早已經用在了生產當中。我們知道ES6在大部分瀏覽器還是跑不通的,因此我們使用了偉大的Babel來進行編譯。很多人可能沒有關心過,...
摘要:剛剛發布,官網自稱最大的特點就是零配置。本文就詳細介紹一下實戰那些事兒。自動刷新監聽本地源代碼的變化,自動重新構建刷新瀏覽器。自動發布更新完代碼后,自動構建出線上發布代碼并傳輸給發布系統。代碼塊,一個由多個模塊組合而成,用于代碼合并與分割。 webpack4.0剛剛發布,官網自稱4.0最大的特點就是零配置。本文就詳細介紹一下webpack4.0實戰那些事兒。 1 什么是WebPack ...
摘要:雖然今年沒有換工作的打算但為了跟上時代的腳步還是忍不住整理了一份最新前端知識點知識點匯總新特性,語義化瀏覽器的標準模式和怪異模式和的區別使用的好處標簽廢棄的標簽,和一些定位寫法放置位置和原因什么是漸進式渲染模板語言原理盒模型,新特性,偽 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總1.HTMLHTML5新特性,語義化瀏覽器的標準模式和怪...
閱讀 3970·2021-11-23 10:09
閱讀 1338·2021-11-23 09:51
閱讀 2939·2021-11-23 09:51
閱讀 1585·2021-09-07 09:59
閱讀 2354·2019-08-30 15:55
閱讀 2292·2019-08-30 15:55
閱讀 2949·2019-08-30 15:52
閱讀 2560·2019-08-26 17:04