摘要:使用的時候只需要安裝你想要的階段就可以了然后添加進(jìn)你的配置文件。為了顯出的能耐,我們分別配個用和支持的先來配使用的首先安裝然后配置需要注意的是,雖然沒有出現(xiàn)在配置里,但仍然需要安裝,因為依賴它。
Babel介紹
Babel 把用最新標(biāo)準(zhǔn)編寫的 JavaScript 代碼向下編譯成可以在今天隨處可用的版本。 這一過程叫做“源碼到源碼”編譯, 也被稱為轉(zhuǎn)換編譯。
15 年 11 月,Babel 發(fā)布了 6.0 版本。相較于前一代 Babel 5,新一代 Babel 更加模塊化, 將所有的轉(zhuǎn)碼功能以插件的形式分離出去,默認(rèn)只提供 babel-core。原本只需要裝一個 babel ,現(xiàn)在必須按照自己的需求配置,靈活性提高的同時也提高了使用者的學(xué)習(xí)成本。
npm i babel
已經(jīng)棄用,你能下載到的僅僅是一段 console.warn,告訴你 babel 6 不再以大雜燴的形式提供轉(zhuǎn)碼功能了。
例如,Babel 能夠?qū)⑿碌?ES2015 箭頭函數(shù)語法:
let fun = () => console.log("babel")
轉(zhuǎn)譯為:
"use strict"; var fun = function fun() { return console.log("babel"); };
不過 Babel 的用途并不止于此,它支持語法擴(kuò)展,能支持像 React 所用的 JSX 語法,更重要的是,Babel 的一切都是簡單的插件,誰都可以創(chuàng)建自己的插件,利用 Babel 的全部威力去做任何事情。
再進(jìn)一步,Babel 自身被分解成了數(shù)個核心模塊,任何人都可以利用它們來創(chuàng)建下一代的 JavaScript 工具。
Babel 的 CLI 是一種在命令行下使用 Babel 編譯文件的簡單方法。
讓我們先全局安裝它來學(xué)習(xí)基礎(chǔ)知識。
$ npm install --global babel-cli
我們可以這樣來編譯我們的第一個文件:
$ babel my-file.js
這將把編譯后的結(jié)果直接輸出至終端。使用 --out-file 或著 -o 可以將結(jié)果寫入到指定的文件。
$ babel example.js --out-file compiled.js # 或 $ babel example.js -o compiled.js
如果我們想要把一個目錄整個編譯成一個新的目錄,可以使用 --out-dir 或者 -d。.
$ babel src --out-dir lib # 或 $ babel src -d libbabel-core
如果你需要以編程的方式來使用 Babel,可以使用 babel-core 這個包。
babel-core 的作用是把 js 代碼分析成 ast ,方便各個插件分析語法進(jìn)行相應(yīng)的處理。有些新語法在低版本 js 中是不存在的,如箭頭函數(shù),rest 參數(shù),函數(shù)默認(rèn)值等,這種語言層面的不兼容只能通過將代碼轉(zhuǎn)為 ast,分析其語法后再轉(zhuǎn)為低版本 js。
首先安裝 babel-core。.
$ npm install babel-core
var babel = require("babel-core");
字符串形式的 JavaScript 代碼可以直接使用 babel.transform 來編譯。
babel.transform("code();", options); // => { code, map, ast }
如果是文件的話,可以使用異步 api:
babel.transformFile("filename.js", options, function(err, result) { result; // => { code, map, ast } });
或者是同步 api:
babel.transformFileSync("filename.js", options); // => { code, map, ast }其他用法
還可以通過babel-register和babel-node使用Babel,但由于這兩種用法不適合生產(chǎn)環(huán)境故省略。
配置 Babel你或許已經(jīng)注意到了,目前為止通過運行 Babel 自己我們并沒能“翻譯”代碼,而僅僅是把代碼從一處拷貝到了另一處。原因就是從Babel 6以后, 默認(rèn)的插件被移除, 如果沒有指定一個插件,Babel將會原樣輸出, 不會進(jìn)行編譯。
你可以通過安裝插件(plugins)或預(yù)設(shè)(presets,也就是一組插件)來指示 Babel 去做什么事情。
插件只是單一的功能,例如
es2015-arrow-functions
es2015-classes
es2015-for-of
es2015-spread
以下是安裝箭頭函數(shù)的插件方式
npm install --save-dev babel-plugin-transform-es2015-arrow-functions
如果我們一個一個引人功能單一的插件的話顯得特別麻煩,通常我們用的更多的是預(yù)設(shè)。插件和預(yù)設(shè)通常寫入到配置文件中。可以將配置寫入package.json的‘babel’屬性里,或者是一個多帶帶的.babelrc文件。
.babelrc在我們告訴 Babel 該做什么之前,你需要做的就是在項目的根路徑下創(chuàng)建 .babelrc 文件。然后輸入以下內(nèi)容作為開始:
{ "presets": [], "plugins": [] }
這個文件就是用來讓 Babel 做你要它做的事情的配置文件。
babel-preset-es2015預(yù)設(shè) babel-preset 系列打包了一組插件,類似于餐廳的套餐。如 babel-preset-es2015 打包了 es6 的特性,babel-preset-stage-0 打包處于 strawman 階段的語法
我們需要安裝 "es2015" Babel 預(yù)設(shè):
$ npm install --save-dev babel-preset-es2015
我們修改 .babelrc 來包含這個預(yù)設(shè)。
{ "presets": [ + "es2015" ], "plugins": [] }
同樣的,還有babel-preset-2016,babel-preset-2017。
babel-preset-latestlatest是一個特殊的presets,包括了es2015,es2016,es2017的插件(目前為止,以后有es2018也會包括進(jìn)去)。即總是包含最新的編譯插件。
babel-preset-env上面提到的各種preset的問題就是: 它們都太”重”了, 即包含了過多在某些情況下不需要的功能. 比如, 現(xiàn)代的瀏覽器大多支持ES6的generator, 但是如果你使用babel-preset-es2015, 它會將generator函數(shù)編譯為復(fù)雜的ES5代碼, 這是沒有必要的。但使用babel-preset-env, 我們可以聲明環(huán)境, 然后該preset就會只編譯包含我們所聲明環(huán)境缺少的特性的代碼,因此也是比較推薦的方式。
安裝babel-preset-env
npm install babel-preset-env --save-dev
添加配置
{ "presets": ["env"] }
當(dāng)沒有添加任何的配置選項時,babel-preset-env默認(rèn)行為是和babel-preset-latest是一樣的。
下面我們通過一些例子來看babel-preset-env的配置是如何使用的:
指定支持主流瀏覽器最新的兩個版本以及IE 7+:
"presets": [ [ "env", { "targets": { "browsers": ["last 2 versions", "ie >= 7"] } } ] ] }
支持超過市場份額5%的瀏覽器:
"targets": { "browsers": "> 5%" }
某個固定版本的瀏覽器:
"targets": { "chrome": 56 }
更多的配置請查看官方文檔
babel-preset-stage-x官方預(yù)設(shè)(preset), 有兩種,一個是按年份(babel-preset-2017),一個是按階段(babel-preset-stage-0)。 這主要是根據(jù)TC39 委員會ECMASCRPIT 發(fā)布流程來制定的。TC39 委員會決定,從2016年開始,每年都會發(fā)布一個版本,它包括每年期限內(nèi)完成的所有功能,同時ECMAScript的版本號也按年份編制,就有了ES2016, ES2017。所以也就有了babel-present-2016, babel-preset-2017, 對每一年新增的語法進(jìn)行轉(zhuǎn)化。babel-preset-latest 就是把所有es2015, es2016, es2017 全部包含在一起了。
最終在階段 4 被標(biāo)準(zhǔn)正式采納。
以下是4 個不同階段的(打包的)預(yù)設(shè):
babel-preset-stage-0
babel-preset-stage-1
babel-preset-stage-2
babel-preset-stage-3
注意 stage-4 預(yù)設(shè)是不存在的因為它就是上面的 es2017 預(yù)設(shè)。
以上每種預(yù)設(shè)都依賴于緊隨的后期階段預(yù)設(shè),數(shù)字越小,階段越靠后,存在依賴關(guān)系。也就是說stage-0是包括stage-1的,以此類推。也就是說這些stage包含的特性是比latest更新的特性但還未被寫入標(biāo)準(zhǔn)進(jìn)行發(fā)布。
使用的時候只需要安裝你想要的階段就可以了:
$ npm install --save-dev babel-preset-stage-2
然后添加進(jìn)你的 .babelrc 配置文件。但是要注意如果沒有提供es2017相關(guān)的預(yù)設(shè),preset-stage-X 這種階段性的預(yù)設(shè)也不能用。
執(zhí)行 Babel 生成的代碼Babel 幾乎可以編譯所有時新的 JavaScript 語法,但對于 APIs 來說卻并非如此。例如: Promise、Set、Map 等新增對象,Object.assign、Object.entries等靜態(tài)方法。
為了達(dá)成使用這些新API的目的,社區(qū)又有2個實現(xiàn)流派:babel-polyfill和babel-runtime+babel-plugin-transform-runtime。
這兩個模塊功能幾乎相同,就是轉(zhuǎn)碼新增 api,模擬 es6 環(huán)境,但實現(xiàn)方法完全不同。babel-polyfill 的做法是將全局對象通通污染一遍,比如想在 node 0.10 上用 Promise,調(diào)用 babel-polyfill 就會往 global 對象掛上 Promise 對象。對于普通的業(yè)務(wù)代碼沒有關(guān)系,但如果用在模塊上就有問題了,會把模塊使用者的環(huán)境污染掉。
babel-runtime 的做法是自己手動引入 helper 函數(shù),還是上面的例子,const Promise = require("babel-runtime/core-js/promise") 就可以引入 Promise。
但 babel-runtime 也有問題,第一,很不方便,第二,在代碼中中直接引入 helper 函數(shù),意味著不能共享,造成最終打包出來的文件里有很多重復(fù)的 helper 代碼。所以,babel 又開發(fā)了 babel-plugin-transform-runtime,這個模塊會將我們的代碼重寫,如將 Promise 重寫成 _Promise(只是打比方),然后引入_Promise helper 函數(shù)。這樣就避免了重復(fù)打包代碼和手動引入模塊的痛苦。
babel-polyfill為了解決這個問題,我們使用一種叫做 Polyfill(代碼填充,也可譯作兼容性補(bǔ)丁) 的技術(shù)。 簡單地說,polyfill即是在當(dāng)前運行環(huán)境中用來復(fù)制(意指模擬性的復(fù)制,而不是拷貝)尚不存在的原生 api 的代碼。能讓你提前使用還不可用的 APIs,Array.from 就是一個例子。
Babel 用了優(yōu)秀的 core-js 用作 polyfill,并且還有定制化的 regenerator 來讓 generators(生成器)和 async functions(異步函數(shù))正常工作。
要使用 Babel polyfill,首先用 npm 安裝它:
$ npm install --save babel-polyfill
然后只需要在文件頂部導(dǎo)入 polyfill 就可以了:
import "babel-polyfill";babel-runtime
與 babel-polyfill 一樣,babel-runtime 的作用也是模擬 ES2015 環(huán)境。只不過,babel-polyfill 是針對全局環(huán)境的,引入它,我們的瀏覽器就好像具備了規(guī)范里定義的完整的特性 – 雖然原生并未實現(xiàn)。
babel-runtime 更像是分散的 polyfill 模塊,我們可以在自己的模塊里多帶帶引入,比如 require(‘babel-runtime/core-js/promise’) ,它們不會在全局環(huán)境添加未實現(xiàn)的方法,只是,這樣手動引用每個 polyfill 會非常低效。我們借助 Runtime transform 插件來自動化處理這一切。
通過安裝 babel-plugin-transform-runtime 和 babel-runtime 來開始。
$ npm install --save-dev babel-plugin-transform-runtime $ npm install --save babel-runtime
然后更新 .babelrc:
{ "plugins": [ "transform-runtime", "transform-es2015-classes" ] }
現(xiàn)在,Babel 會把這樣的代碼:
class Foo { method() {} }
編譯成:
import _classCallCheck from "babel-runtime/helpers/classCallCheck"; import _createClass from "babel-runtime/helpers/createClass"; let Foo = function () { function Foo() { _classCallCheck(this, Foo); } _createClass(Foo, [{ key: "method", value: function method() {} }]); return Foo; }();
這樣就不需要把 _classCallCheck 和 _createClass 這兩個助手方法放進(jìn)每一個需要的文件里去了。
那什么時候用 babel-polyfill 什么時候用 babel-runtime 呢?如果你不介意污染全局變量(如上面提到的業(yè)務(wù)代碼),放心大膽地用 babel-polyfill ;而如果你在寫模塊,為了避免污染使用者的環(huán)境,沒的選,只能用 babel-runtime + babel-plugin-transform-runtime。
options很多預(yù)設(shè)和插件都有選項用于配置他們自身的行為。 例如,很多轉(zhuǎn)換器都有“寬松”模式,通過放棄一些標(biāo)準(zhǔn)中的行為來生成更簡化且性能更好的代碼。
要為插件添加選項,只需要做出以下更改:
{ "plugins": [ "transform-runtime", - "transform-es2015-classes", + ["transform-es2015-classes", { "loose": true }] ] }
plugins/presets排序:
具體而言,plugins優(yōu)先于presets進(jìn)行編譯。
plugins按照數(shù)組的index增序(從數(shù)組第一個到最后一個)進(jìn)行編譯。
presets按照數(shù)組的index倒序(從數(shù)組最后一個到第一個)進(jìn)行編譯。因為作者認(rèn)為大部分會把presets寫成["es2015", "stage-0"]。具體細(xì)節(jié)可以看這個。
webpack 中定義 babel-loader很少有大型項目僅僅需要 babel,一般都是 babel 配合著 webpack 或 glup 等編譯工具一起上的。
為了顯出 babel 的能耐,我們分別配個用 babel-polyfill 和 babel-runtime 、支持 react 的webpack.config.js
先來配使用 babel-runtime 的:
首先安裝:
npm install babel-loader babel-core babel-preset-es2015 babel-plugin-transform-runtime webpack --save-dev
npm install babel-runtime --save
然后配置
module: { loaders: [{ loader: "babel", test: /.jsx?$/, include: path.join(__dirname, "src"), query: { plugins: ["transform-runtime"], presets: [ ["env", { "targets": { "chrome": 52 }, "modules": false, "loose": true }], "stage-2", "react" ], } }] }
需要注意的是,babel-runtime 雖然沒有出現(xiàn)在配置里,但仍然需要安裝,因為 transform-runtime 依賴它。
再來個 babel-polyfill 的:
entry: [ "babel-polyfill", "src/index.jsx", ], module: { loaders: [{ loader: "babel", test: /.jsx?$/, include: path.join(__dirname, "src"), query: { presets: [ ["env", { "targets": { "chrome": 52 }, "modules": false, "loose": true }], "stage-2", "react", ], } }] }
參考文檔:
http://babeljs.io/
https://github.com/thejamesky...
https://excaliburhan.com/post...
https://icyfish.me/2017/05/18...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/81275.html
摘要:在項目根目錄下創(chuàng)建一個文件,注意這是個配置文件,以點號開頭,沒有后綴。提供了一種可以在瀏覽器中使用的方法,只需兩步就能一勞永逸。 1.在命令行中使用 Babel Babel 官方推薦將 Babel 安裝在本地,因為 Babel 的不同版本以及不同轉(zhuǎn)碼規(guī)則會起到不同的效果,全局安裝會帶來不必要的麻煩。在命令提示符中轉(zhuǎn)到自己的項目目錄下: npm install --save-dev ba...
摘要:介紹把用最新標(biāo)準(zhǔn)編寫的代碼向下編譯成可以在今天隨處可用的版本。這主要是根據(jù)委員會發(fā)布流程來制定的。最終在階段被標(biāo)準(zhǔn)正式采納。也就是說這些包含的特性是比更新的特性但還未被寫入標(biāo)準(zhǔn)進(jìn)行發(fā)布。 Babel-loader介紹 Babel 把用最新標(biāo)準(zhǔn)編寫的 JavaScript 代碼向下編譯成可以在今天隨處可用的版本。 這一過程叫做源碼到源碼編譯, 也被稱為轉(zhuǎn)換編譯。 安裝 npm i ba...
摘要:入門什么是是一個廣泛使用的轉(zhuǎn)碼器,可以將代碼轉(zhuǎn)為代碼,從而在現(xiàn)有環(huán)境執(zhí)行。 babel6 入門 什么是babel Babel是一個廣泛使用的轉(zhuǎn)碼器,可以將ES6代碼轉(zhuǎn)為ES5代碼,從而在現(xiàn)有環(huán)境執(zhí)行。 因為es6比es5的代碼更為適合編寫程序,但是因為歷史的原因,現(xiàn)在普遍的瀏覽器并不支持es6代碼(普遍支持es5),即如果你寫es6代碼之后,在瀏覽器上運行出錯,因為瀏覽器的javas...
摘要:安裝然后在的配置文件加入入口文件引入這樣就可以啦,還是可以減少很多代碼量的。是參數(shù),等同于執(zhí)行正常。這個包很簡單,就是引用了和,然后生產(chǎn)環(huán)境把它們編譯到目錄下,做了映射,供使用。 引入 這個問題是對自己的發(fā)問,但我相信會有很多跟我一樣的同學(xué)。對于 babel 的使用,近半年來一直停留在與 webpack 結(jié)合使用,以及在瀏覽器開發(fā)環(huán)境下。導(dǎo)致很多 babel 的包,我都不清楚他們是干嘛...
摘要:在做項目中一直使用的是腳手架搭建的環(huán)境,一直沒有仔細(xì)的去了解這一工具,這周末抽出一天時間通過官網(wǎng)還有各種博客文章算是了解了一些內(nèi)容,起碼可以在項目中自己完成的配置了。不過好像目前瀏覽器端對這種諸如之類的方法支持的還不錯了。 在做項目中一直使用的是腳手架搭建的環(huán)境,一直沒有仔細(xì)的去了解 babel 這一工具,這周末抽出一天時間通過官網(wǎng)還有各種博客文章算是了解了一些內(nèi)容,起碼可以在項目中自...
閱讀 2689·2021-10-12 10:12
閱讀 2335·2021-09-02 15:41
閱讀 2561·2019-08-30 15:55
閱讀 1399·2019-08-30 13:05
閱讀 2430·2019-08-29 11:21
閱讀 3535·2019-08-28 17:53
閱讀 3022·2019-08-26 13:39
閱讀 801·2019-08-26 11:50