升級到Babel 7的經驗

Babel的最新版本Babel 7 已經在Henry Zhu的不斷努力下發布了,他真的是全身心地投入到了Babel的開發中,而Babel對於前端界的貢獻也是有目共睹,沒有這個神奇的編譯器,前端界要落地ES6語法恐怕還要再等十年。html

最近我在給本身團隊的UI組件庫升級到Babel 7,沒有想象中那麼難,但也有一些須要注意的問題,這裏分享一些升級的體會和經驗。前端

關於stage-x插件的廢棄

Babel 7的改動仍是很多的,一個比較大的改動在於移除了以前的stage-x插件,根據官方博客的解釋,stage-x插件本來是對應於ECMA Script提案中的不一樣階段,每一個階段有不一樣特性,而stage-x插件事實上就是集合這個階段中幾種特性轉譯的插件,好比咱們最常常看到的babel-preset-stage-0,其實就是這樣的:react

module.exports = {
  presets: [
    require("babel-preset-stage-1")
  ],
  plugins: [
    require("babel-plugin-transform-do-expressions"),
    require("babel-plugin-transform-function-bind")
  ]
};

每一個stage插件都會包含下一階段的全部插件,這就致使你們爲了能用上大多數特性,紛紛採用了babel-preset-stage-0,React項目中,咱們最常常看到的babelrc配置是這樣的:git

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

然而,提案一直在變,現在是stage 0的特性,可能以後就進入到了stage 1,也可能以後直接被否決拋棄掉,並不會進入到ES規範中。那麼babel是否是應該更新這些stage插件呢?若是更新了,現階段大量前端項目、npm庫都在使用這個stage插件,會不會忽然發現就編譯不了某個特性了呢?github

到底應該遵循規範,仍是應該遷就老項目作兼容呢?

最後Babel團隊作出來的決定是,廢棄掉stage-x插件!這不只僅是關乎上面這個問題,因爲你們已經習慣了stage的配置,對於其中封裝的各個特性早已再也不關心,廢除掉stage-x插件,開發者就得加上本身須要的插件,每一個插件對應一個提案中的特性,這樣項目中的配置也能更清晰。shell

另外,以前的命名也由@babel/plugin-transform-改成@babel/plugin-proposal-,就是爲了強調這只是一個提案中的特性,並不能確保它會出如今下一代的ES規範中。express

es2015 插件 -> env 插件

babel-preset-env已經發布了一段時間,它相比es2015能夠更加靈活地配置,Babel 7宣佈廢棄babel-preset-es201x而採用新的env插件也是理所固然,這個插件的配置再也不贅述,能夠參考官方文檔npm

說說babel-upgrade

爲了讓你更方便的升級到Babel 7,官方提供了一個工具babel-upgrade,對於已有的項目,只須要運行這樣一行命令就能夠了:json

npx babel-upgrade --write --install

可是這就是爲何我先寫了前面這兩節的緣由,這個工具的本質其實就是把以前的es2015換成envstage-x換成各類proposal-xxx,而且加上了@babel做爲新的Babel 7生態統一使用的scope。若是以前的項目使用了stage-x插件,就會多出大量的插件,其實這裏面大部分插件都是無需使用的,你能夠根據項目中用到的特性適當刪減。babel

事實上,我最後項目中只使用了一個插件,babelrc配置以下:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "modules": false
            }
        ],
        "@babel/preset-react"
    ],
    "plugins": ["@babel/proposal-class-properties"]
}

說說babel-plugin-transform-class-properties

這個插件在React項目中十分經常使用,由於咱們常常須要將React組件類中的方法的this綁定到組件自己,若是不用箭頭函數,咱們就須要使用bind將函數一個個綁定好,但若是可使用箭頭函數在class字段中直接綁定的話,就很是方便了,即:

class Bork {
    boundFunction = () => {
        return this.state;
    }
}

這樣,箭頭函數被看成成class的屬性來看待,this也不會指向undefined

這個特性就須要babel-plugin-transform-class-properties來轉譯,這個插件在原來是包含在stage-2裏面的,如今,就須要單獨引入。
固然其實這裏最好是引入@babel/plugin-proposal-class-properties,更加符合規範。

這個是屬於Class Field提案。

相關文章
相關標籤/搜索