背景
babel的官網說babel是下一代的js語法編譯器,現在自己也在很多項目中使用了babel,可是自己對babel的認識呢,只停留在從google和別人項目中copy的配置代碼上,內心感到很不安,最近花了點時間整理了一下,分享給大伙。
babel常用配置
通常在前端或node項目中,進行以下配置:
入口文件app.babel.js里面配置:
// babel require('babel-core/register')({ presets: ['es2015', 'stage-0'] }); require('babel-polyfill'); require('./app.js');
.babelrc文件中的設置:
{ "presets": ["es2015", "stage-0"] }
babel基礎概念
1.babel-core
新的js語法之前是不存在的,需要將js代碼分析抽象的語法樹 ,方便各個插件分析語法進行相應的處理成低版本的js;
2.babel-register
改寫了require命令,會對.js、jsx、.es、es6 后綴的模塊都會先轉碼,但並不會對當前文件進行轉碼;由於該轉碼是實時的,所以不能用在生產環境中。
3.babelrc文件
babel-core只是生成了語法樹,並沒有轉碼,轉碼工作由插件完成。自從babel升級到6.x之后,babel的插件都是可以插拔的,只有設置了相應的插件,babel才能知道如何處理js代碼。
.babelrc主要對presets、plugins進行設置,其中presets主要是一套預設置的插件,如es-2015、stage-0等,plugins可以讓用戶選取需要的單個插件。
目前babel提供了幾個官方的preset,主要包括:env es2015 es2016 es2017 flow latest react 。設置presets的時候需要提前npm安裝相應的插件,插件名格式:babel-preset-xxx;如下:
{ "presets": ["es2015"] } npm install babel-preset-es2015
如果不需要一套plugins的預設置,可以通過plugins屬性引入所需的plugin,比如以下的設置就會引入編譯class函數的功能。
{ "plugins": ["transform-es2015-classes"] }
需要注意的是,某些插件是不被presets預置的,如常用的
transform-runtime
插件和
transform-remove-console
插件。
關於presets和plugins的優先順序一般遵從3個原則:
-
plugins優先於presets進行編譯。
-
plugins按照數組的index增序(從數組第一個到最后一個)進行編譯。
-
presets按照數組的index倒序(從數組最后一個到第一個)進行編譯。
-
詳細信息可以查看 官方文檔
4.babel-polyfill
polyfill擁有自定義的regenerator runtime 和core-js;它模擬了ES2015的環境,一般使用在應用程序中,而不是當做庫和工具使用;比如說babel-node中自帶了babel-polyfill,babel-polyfill為node提供了ES6的REPL環境。REPL,即read-eval-print-loop交互式解釋器。詳情可參考
阮老師的文章。
babel幾乎能翻譯所有的js新語法,但是對於APIs卻並非如此,如新增對象Promise、Set、Map等,靜態方法Object.assign等,這就需要創造一個ES6的運行環境。
可以通過babel-polyfill來轉碼新API,其實現辦法就是向全局變量上掛新增的對象或在原型鏈上增加方法,如在node環境下將Promise掛在global對象上。缺點就是污染全局變量。
還有一個避免全局污染的方法就是使用babel-runtime + babel-plugins-runtime-transform;babel-runtime 更像是分散的polyfill 模塊,我們可以在自己的模塊里單獨引入,比如 require(‘babel-runtime/core-js/promise’) ,它們不會在全局環境添加未實現的方法,只是這樣手動引用每個 polyfill 會非常麻煩。我們借助 Runtime transform 插件來自動化處理這一切。
webpack中如何使用babel
1.使用babel-runtime
需要安裝babel-runtime和babel-plugin-transform-runtime
module: { loaders: [{ loader: 'babel', test: /\.js/, include: path.join(__dirname, 'src'), query: { plugins: ['transform-runtime'], presets: [ 'es2015', 'stage-0'], }}] }
2.使用babel-polyfi
將babel-polyfill放在入口設置處
entry: [ 'babel-polyfill','src/index.js', ], module: { loaders: [{ loader: 'babel', test: /\.js/, include: path.join(__dirname, 'src'), query: { presets: ['es2015', 'stage-0'] }}] }
參考資料: