爲了支持業務中少許的es6+的高級特性,最近在研究了一下babel的墊片,現將此整理爲文字,以下。node
一、先來理解下 babel 究竟是作什麼的?react
簡單來說, babel解決 語法層面的問題。用於將ES6+的高級語法轉爲ES5。
二、babel polyfill 又是作什麼的?webpack
若是要解決 API層面的問題,須要使用墊片。好比常見的有babel-polyfill
、babel-runtime
和babel-plugin-transform-runtime
。
理清了他們之間的關係,那麼再正式來說講有關polyfill
的二三事。git
babel polyfill 有三種es6
* babel-polyfill * babel-runtime * babel-plugin-transform-runtime
babel-polyfill
經過向全局對象和內置對象的prototype上添加方法來實現的。因此這會形成全局空間污染。github
babel-polyfill
使用的兩種方式一、webpack.config.js 中:
配置webpack.config.js
裏的entry
設置爲entry: ['babel-polyfill',path.join(__dirname, 'index.js')]
web
二、業務 js 中:
在webpack.config.js
配置的主入口index.js
文件的最頂層鍵入promise
import 'babel-polyfill'
二者打印出來的大小都是同樣的,打包後大小是280KB,若是沒有使用babel-polyfill
,大小是3.43kb。兩則相差大概81.6倍。緣由是webpack
把babel-polyfill
總體所有都打包進去了。而babel-polyfill
確定也實現了全部ES6新API
的墊片,文件必定不會小。瀏覽器
那麼有沒有一種辦法,根據實際代碼中用到的ES6
新增API ,來使用對應的墊片,而不是所有加載進去呢?
是的,有的。那就是 babel-runtime
& babel-plugin-transform-runtime
,他們能夠實現按需加載。babel
簡單說 babel-runtime 更像是一種按需加載的實現,好比你哪裏須要使用 Promise,只要在這個文件頭部
import Promise from 'babel-runtime/core-js/promise'
就好了。
不過若是你許多文件都要使用 Promise,難道每一個文件都要 import
一下嗎?固然不是,Babel 官方已考慮這種狀況,只須要使用 babel-plugin-transform-runtime
就能夠解決手動 import
的苦惱了。
babel-plugin-transform-runtime
裝了就不須要裝 babel-runtime
了,由於前者依賴後者。
總的來講,babel-plugin-transform-runtime
就是能夠在咱們使用新 API 時 自動 import babel-runtime 裏面的 polyfill,具體插件作了如下三件事情:
babel-plugin-transform-runtime
優勢:
在 .babelrc 中配置:
plugins:\["tranform-runtime"\]
打包後大小爲 17.4kb,比以前的280kb要小不少。
若是不想本身設置一堆插件的話,官方有env
,react
,flow
三個 Presets。即預安裝了 plugins 的配置。
presets 屬性告訴 Babel 要轉換的源碼使用了哪些新的語法特性, presets 是一組 Plugins 的集合。如:
babel-preset-es2015: 能夠將es6的代碼編譯成es5
babel-preset-es2016: 能夠將es7的代碼編譯爲es6
babel-preset-es2017: 能夠將es8的代碼編譯爲es7
babel-preset-latest: 支持現有全部ECMAScript版本的新特性
當咱們須要轉換es6語法時,能夠在 .babelrc 的 plugins 中按需引入一下插件,好比:check-es2015-constants
、es2015-arrow-functions
、es2015-block-scoped-functions
等等幾十個不一樣做用的 plugin。.babelrc
中配置項多是以下方式:
{ "plugins": \[ "check-es2015-constants", "es2015-arrow-functions", "es2015-block-scoped-functions", // ... \] }
但 Babel 團隊爲了方便,將同屬 ES2015 的幾十個 Transform Plugins 集合到 babel-preset-es2015
一個 Preset 中,這樣咱們只須要在 .babelrc
的 presets 加入 ES2015 一個配置就能夠完成所有 ES2015 語法的支持了。.babelrc
中配置以下:
{ "presets": \[ "es2015" \] }
這個比較好理解,就是爲了支持 TC39 對於草案階段的 ES 最新特性而開發的 presets。
官方和民間提供了不少的轉換插件,用於指定對某一項 ES 高級特性進行轉換。
官方見:https://babeljs.io/docs/en/pl...
這種插件可讓Babel
來解析特殊類型的語法。
{ "parserOpts": { "plugins": \["jsx", "flow"\] } }
見文檔:https://github.com/jamiebuild...
開發採用了 AST 抽象語法樹,相似於 Eslint 插件開發。
export default function () { return { visitor: { Identifier(path) { const name = path.node.name; // reverse the name: JavaScript -> tpircSavaJ path.node.name = name.split("").reverse().join(""); } } }; }
babel 用途是語法轉換,因此webpack 中須要用到 babel-loader
。而 babel-core
是 Babel 編譯器的核心,所以也就意味着若是咱們須要使用 babel-loader
進行 es6 轉碼的話,咱們首先須要安裝 babel-core
。
使用場景建議:
以上,若有寫的不正確或者有疑問的地方請留言。未完待續,本文會持續更新babel相關知識。