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


大家知道,將ES6代碼編譯為ES5時,我們常用到Babel這個編譯工具。大家參考一些網上的文章或者官方文檔,里面常會建議大家在.babelrc中輸入如下代碼:

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

 

我們現在來說明下這個配置文件是什么意思。首先,這個配置文件是針對babel 6的。Babel 6做了一系列模塊化,不像Babel 5一樣把所有的內容都加載。比如需要編譯ES6,我們需要設置presets為"es2015",也就是預先加載es6編譯的相關模塊,如果需要編譯jsx,需要預先加載"react"這個模塊。那問題來了,這個"stage-0"又代表什么呢? 有了"react-0",是否又有諸如"stage-1", "stage-2"等等呢?

 

事實上, ”stage-0"是對ES7一些提案的支持,Babel通過插件的方式引入,讓Babel可以編譯ES7代碼。當然由於ES7沒有定下來,所以這些功能隨時肯能被廢棄掉的。現在我們來一一分析里面都有什么。

 

1. 法力無邊的stage-0

 

為什么說“stage-0” 法力無邊呢,因為它包含stage-1, stage-2以及stage-3的所有功能,同時還另外支持如下兩個功能插件:

 

用過React的同學可能知道,jsx對條件表達式支持的不是太好,你不能很方便的使用if/else表達式,要么你使用三元表達,要么用函數。例如你不能寫如下的代碼:

 

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 這個插件就是為了方便在 jsx寫if/else表達式而提出的,我們可以重寫下代碼。

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, 這個插件其實就是提供過 :: 這個操作符來方便快速切換上下文, 如下面的代碼:

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)

// 再來一個復雜點的樣例

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'

 

如果想更屌點,還可以寫出更牛逼的代碼:

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個插件:

 

今天就到這里了,改天我們接着分析下"stage-2"和"stage-3", 它們又有什么新的特性呢,讓我們拭目以待吧。

 


免責聲明!

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



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