如何區(qū)分Babel中的stage-0,stage-1,stage-2以及stage-3

大家知道,將ES6代碼編譯為ES5時(shí),我們常用到Babel這個(gè)編譯工具胞四。大家參考一些網(wǎng)上的文章或者官方文檔刚操,里面常會(huì)建議大家在.babelrc中輸入如下代碼:

{
    "presets": [
     "es2015",
     "react",
     "stage-0"
    ],
    "plugins": []
}

我們現(xiàn)在來說明下這個(gè)配置文件是什么意思闸翅。首先,這個(gè)配置文件是針對(duì)babel 6的菊霜。Babel 6做了一系列模塊化坚冀,不像Babel 5一樣把所有的內(nèi)容都加載。比如需要編譯ES6鉴逞,我們需要設(shè)置presets為"es2015"记某,也就是預(yù)先加載es6編譯的相關(guān)模塊,如果需要編譯jsx构捡,需要預(yù)先加載"react"這個(gè)模塊液南。那問題來了,這個(gè)"stage-0"又代表什么呢勾徽? 有了"react-0"滑凉,是否又有諸如"stage-1", "stage-2"等等呢?
事實(shí)上, ”stage-0"是對(duì)ES7一些提案的支持畅姊,Babel通過插件的方式引入闪幽,讓Babel可以編譯ES7代碼。當(dāng)然由于ES7沒有定下來涡匀,所以這些功能隨時(shí)肯能被廢棄掉的《㈦纾現(xiàn)在我們來一一分析里面都有什么。

1. 法力無邊的stage-0

為什么說“stage-0” 法力無邊呢陨瘩,因?yàn)樗瑂tage-1, stage-2以及stage-3的所有功能腕够,同時(shí)還另外支持如下兩個(gè)功能插件:
transform-do-expressions
transform-function-bind
用過React的同學(xué)可能知道,jsx對(duì)條件表達(dá)式支持的不是太好舌劳,你不能很方便的使用if/else表達(dá)式帚湘,要么你使用三元表達(dá),要么用函數(shù)甚淡。例如你不能寫如下的代碼:

var App = React.createClass({

    render(){
        let { color } = this.props;

        return (
            <div className="parents">
                {
                    if(color == 'blue') { 
                        <BlueComponent/>; 
                    }else if(color == 'red') { 
                        <RedComponent/>; 
                    }else { 
                        <GreenComponent/>; }
                    }
                }
            </div>
        )
    }
})

在React中你只能寫成這樣:

var App = React.createClass({

    render(){
        let { color } = this.props;


        const getColoredComponent = color => {
            if(color === 'blue') { return <BlueComponent/>; }
            if(color === 'red') { return <RedComponent/>; }
            if(color === 'green') { return <GreenComponent/>; }
        }


        return (
            <div className="parents">
                { getColoredComponent(color) }
            </div>
        )
    }
})

transform-do-expressions 這個(gè)插件就是為了方便在 jsx寫if/else表達(dá)式而提出的大诸,我們可以重寫下代碼。

var App = React.createClass({

    render(){
        let { color } = this.props;

        return (
            <div className="parents">
                {do {
                    if(color == 'blue') { 
                        <BlueComponent/>; 
                    }else if(color == 'red') { 
                        <RedComponent/>; 
                    }else { 
                        <GreenComponent/>; }
                    }
                }}
            </div>
        )
    }
})

再說說 transform-function-bind, 這個(gè)插件其實(shí)就是提供過 :: 這個(gè)操作符來方便快速切換上下文贯卦, 如下面的代碼:

obj::func
// is equivalent to:
func.bind(obj)

obj::func(val)
// is equivalent to:
func.call(obj, val)

::obj.func(val)
// is equivalent to:
func.call(obj, val)

// 再來一個(gè)復(fù)雜點(diǎn)的樣例

const box = {
  weight: 2,
  getWeight() { return this.weight; },
};

const { getWeight } = box;

console.log(box.getWeight()); // prints '2'

const bigBox = { weight: 10 };
console.log(bigBox::getWeight()); // prints '10'

// Can be chained:
function add(val) { return this + val; }

console.log(bigBox::getWeight()::add(5)); // prints '15'

如果想更屌點(diǎn)资柔,還可以寫出更牛逼的代碼:

const { map, filter } = Array.prototype;

let sslUrls = document.querySelectorAll('a')
                ::map(node => node.href)
                ::filter(href => href.substring(0, 5) === 'https');

console.log(sslUrls);
2. 包羅萬象的stage-1

stage-1除了包含stage-2和stage-3,還包含了下面4個(gè)插件:

transform-class-constructor-call(Deprecated)
transform-class-properties
transform-decorators – disabled pending proposal update
transform-export-extensions

深藏不露的stage-2

為什么說 stage-2深藏不露呢撵割,因?yàn)樗艿驼{(diào)贿堰,低調(diào)到你可以忽略它,但事實(shí)上啡彬,它很有內(nèi)涵的羹与。它除了覆蓋stage-3的所有功能,還支持如下兩個(gè)插件:
syntax-trailing-function-commas
transform-object-reset-spread

syntax-trailing-function-commas

這個(gè)插件讓人一看覺得挺沒趣的庶灿,讓人甚至覺得它有點(diǎn)雞肋纵搁。因它不是對(duì)ES6功能的增加,而是為了增強(qiáng)代碼的可讀性和可修改性而提出的往踢。如下面的代碼所示:

// 假設(shè)有如下的一個(gè)函數(shù)腾誉,它有兩個(gè)參數(shù)

function clownPuppiesEverywhere(
  param1,
  param2
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
  'bar'
);

// 有一天,它需要變成3個(gè)參數(shù)菲语,你需要這樣修改

function clownPuppiesEverywhere(
  param1,
- param2
+ param2, // 這一行得加一個(gè)逗號(hào)
+ param3  // 增加參數(shù)param3
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
- 'bar'
+ 'bar', // 這里的修改為逗號(hào)
+ 'baz'  // 增加新的參數(shù)
);

// 看到?jīng)]妄辩? 我們修改了4行代碼。山上。啊啊眼耀。修改了4行代碼。
修改了4行代碼佩憾,嗯嗯嗯哮伟。干花。追求高效的程序猿想想了,以后如果有更多參數(shù)了楞黄,我是不是要改等多行池凄,得想想,代碼改的越少越好鬼廓,于是有了下面的改動(dòng)肿仑。。

// 我們來重新定義一下函數(shù)

function clownPuppiesEverywhere(
  param1,
  param2, // 注意這里碎税,我們加了一個(gè)逗號(hào)喲
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
  'bar', // 這里我們也加了一個(gè)逗號(hào)
);

// 現(xiàn)在函數(shù)需要三個(gè)參數(shù)尤慰,我們來修改下

function clownPuppiesEverywhere(
  param1,
  param2,
+ param3, // 增加params3參數(shù)
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
  'bar',
+ 'baz', // 增加第三個(gè)參數(shù)
);

// 叮叮當(dāng),我們只修改了兩行代碼就完成了雷蹂,好開森
說實(shí)話吧伟端,這個(gè)功能讓人有點(diǎn)很無語。不過程序猿對(duì)干凈代碼的追求真的很讓人感動(dòng)匪煌,還是值得鼓勵(lì)的责蝠。這個(gè)就是stage-2中"尾逗號(hào)函數(shù)”功能。哈哈哈哈萎庭。

transform-object-rest-spread

再來說transform-object-rest-spread霜医, 其實(shí)它是對(duì) ES6中解構(gòu)賦值的一個(gè)擴(kuò)展摩骨,因?yàn)镋S6只支持對(duì)數(shù)組的解構(gòu)賦值玛荞,對(duì)對(duì)象是不支持的。如下面的代碼所示:

// 獲取剩下的屬性

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }

// 屬性展開

let n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }

大放異彩的stage3

為啥說stage3大放異彩呢?因?yàn)樗С执竺ΧΦ腶sync和await, 這兩個(gè)哥們可是解決(Ajax)回調(diào)函數(shù)的終極解決方法呀达舒!管你什么異步,我都可以用同步的思維來寫叹侄,ES7里面非常強(qiáng)悍的存在巩搏。總的來說趾代,它包含如下兩個(gè)插件:
transform-async-to-generator
transform-exponentiation-operator

transform-async-to-generator

transform-async-to-generator主要用來支持ES7中的async和await贯底, 我們可以寫出下面的代碼:

const sleep = (timeout)=>{
    return new Promise( (resolve, reject)=>{
        setTimeout(resolve, timeout)
    })
}

(async ()=>{
    console.time("async");
    await sleep(3000);
    console.timeEnd("async");
})()

再來一個(gè)實(shí)際點(diǎn)的例子

const fetchUsers = (user)=>{
    return window.fetch(`https://api.douban.com/v2/user/${user}`).then( res=>res.json())
}


const getUser = async (user) =>{
    let users = await fetchUsers(user);
    console.log( users);
}

console.log( getUser("flyingzl"))

提示: 由于asycn和await是ES7里面的內(nèi)容,現(xiàn)階段不建議使用撒强。為了順利運(yùn)行上面的代碼禽捆,建議用webpack進(jìn)行編譯。

transform-exponentiation-operator

transform-exponentiation-operator這個(gè)插件算是一個(gè)語法糖飘哨,可以通過**這個(gè)符號(hào)來進(jìn)行冪操作胚想,想當(dāng)于Math.pow(a,b)。如下面的樣例

// x ** y

let squared = 2 ** 2;

// 相當(dāng)于: 2 * 2

let cubed = 2 ** 3;

// 相當(dāng)于: 2 * 2 * 2

// x **= y

let a = 2;
a **= 2;

// 相當(dāng)于: a = a * a;

let b = 3;
b **= 3;

// 相當(dāng)于: b = b * b * b;
很簡(jiǎn)單也很實(shí)用吧芽隆,哈浊服。使用起來還是蠻方便的统屈。

總結(jié)

通過以上的兩篇文章,我們了解了stage-0,state-1牙躺,stage-2以及stage-3的區(qū)別愁憔。在進(jìn)行實(shí)際開發(fā)時(shí),可以更具需要來設(shè)置對(duì)應(yīng)的stage孽拷。如果省事懶得折騰吨掌,一般設(shè)置為stage-0即可。如果為了防止開發(fā)人員使用某些太新的功能脓恕,我們可以限制到某個(gè)特定的stage即可思犁。如果有其他問題,歡迎大家留言 :-)进肯。 更詳細(xì)的請(qǐng)參考https://babeljs.io/docs/plugins/preset-stage-0/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末激蹲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子江掩,更是在濱河造成了極大的恐慌学辱,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件环形,死亡現(xiàn)場(chǎng)離奇詭異策泣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)抬吟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門萨咕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人火本,你說我怎么就攤上這事危队。” “怎么了钙畔?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵茫陆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我擎析,道長(zhǎng)簿盅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任揍魂,我火速辦了婚禮桨醋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘现斋。我一直安慰自己喜最,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布步责。 她就那樣靜靜地躺著返顺,像睡著了一般禀苦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遂鹊,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天振乏,我揣著相機(jī)與錄音,去河邊找鬼秉扑。 笑死慧邮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舟陆。 我是一名探鬼主播误澳,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼秦躯!你這毒婦竟也來了忆谓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤踱承,失蹤者是張志新(化名)和其女友劉穎倡缠,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茎活,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昙沦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了载荔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盾饮。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖懒熙,靈堂內(nèi)的尸體忽然破棺而出丘损,到底是詐尸還是另有隱情,我是刑警寧澤煌珊,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布号俐,位于F島的核電站,受9級(jí)特大地震影響定庵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜踪危,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一蔬浙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贞远,春花似錦畴博、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽官疲。三九已至,卻和暖如春亮隙,著一層夾襖步出監(jiān)牢的瞬間途凫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國打工溢吻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留维费,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓促王,卻偏偏與公主長(zhǎng)得像犀盟,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蝇狼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容