ECMAScript
ECMAScript是一個由 TC39委員會發(fā)布的標準,JavaScript是對 ECMAScript標準的一個實現(xiàn)子集,可以理解為JavaScript = ECMAScript + 宿主 API(瀏覽器的Dom + Bom API 或者 node的API)宅楞。ECMAScript標準從第三個版本也就是ES3到ES6(也稱為ECMAScript 2015)時隔六年,ES6給 JavaScript帶來革命性的進步蒲肋,加入了類、靜態(tài)模塊體系、塊級作用域等特性兜粘,雖然瀏覽器自身的功能增強申窘、 V8 等 JavaScript 引擎性能提升,但是不同廠商的瀏覽器對于ES6的支持程度參差不齊孔轴,且瀏覽器對規(guī)范的實現(xiàn)速度仍遠遠趕不上規(guī)范更新的速度剃法,很多新新特性不能在全部瀏覽器中運行,在這個環(huán)境因素下路鹰,JavaScript語法編譯器被大廣泛應用贷洲。
Babel是一款JavaScript語法編譯器,主要用于將 ECMAScript 2015+ 版本的代碼轉換為向后兼容的 JavaScript 語法晋柱,以便能夠運行在當前和舊版本的瀏覽器或其他環(huán)境中(輸入以下一代 JavaScript 語法書寫的代碼 => 輸出瀏覽器兼容的 JavaScript 代碼)优构,先來看看使用babel將es6代碼編譯為es5的效果:
// es6的箭頭函數(shù)[1, 2, 3].map((n) => n + 1);
輸出代碼:
//編譯后的es5代碼"use strict";[1,2,3].map(function(n){returnn +1;});
Babel除了對新語法的轉換,還可以通過 Polyfill 方式在目標環(huán)境中添加缺失的特性雁竞。
Babel本身將代碼解析之后再輸出同樣的代碼钦椭,什么都沒有做基本上類似于:
constbabel =code=>code;
我們實際上是使用的Babel插件或者preset(一組插件)轉換我們的代碼,插件分為轉換插件和語法插件(轉換插件會自動啟用語法插件)碑诉。
react-jsx
arrow-functions
block-scoped-functions
block-scoping
classes
computed-properties
destructuring
duplicate-keys
for-of
function-name
instanceof
literals
@babel/preset-env
@babel/preset-flow
@babel/preset-react
@babel/preset-typescript
在使用Babel插件進行編譯時彪腔,插件的使用順序很重要,意思是:如果兩個轉換插件都將處理“程序(Program)”的某個代碼片段进栽,則將根據(jù)轉換插件或preset的排列順序依次執(zhí)行德挣。
插件在 Presets 前運行。
插件順序從前往后排列快毛。
Preset 順序是顛倒的(從后往前)盲厌。
插件和preset都可以接受參數(shù),參數(shù)由插件名和參數(shù)對象組成一個數(shù)組祸泪,可以在配置文件中設置吗浩,參數(shù)對象為一個以參數(shù)名作為鍵(key)的對象。
{"plugins": [? ? ["transform-async-to-module-method",? ? ? {"module":"bluebird","method":"coroutine"}? ? ]? ]}
1没隘、利用?astexplorer.net?創(chuàng)建一個插件
//一個插件就是一個函數(shù)exportdefaultfunction({types: t}) {return{? ? visitor: {? ? ? Identifier(path) {? ? ? ? letname=path.node.name; //reversethename: JavaScript -> tpircSavaJpath.node.name =name.split('').reverse().join('');? ? ? }? ? }? };}
2懂扼、使用 generator-babel-plugin 生成一個插件模板
3、參考 babel-handbook 學習如何創(chuàng)建自己的插件https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md
如需創(chuàng)建一個自己的 preset右蒲,就是導出一個對象阀湿,對象中包括:插件數(shù)組或者其他presets
//只有插件數(shù)組module.exports = function() {? return {? ? plugins: [? ? ? "pluginA",? ? ? "pluginB",? ? ? "pluginC",? ? ]? };}//或者包括其他presets和參數(shù)module.exports = () => ({? presets: [? ? require("@babel/preset-env"),? ],? plugins: [? ? [require("@babel/plugin-proposal-class-properties"), { loose: true }],? ? require("@babel/plugin-proposal-object-rest-spread"),? ],});
使用Babel進行語法編譯時可以根據(jù)項目自身要針對的瀏覽器情況,來配置Babel參數(shù)決定編譯輸出的具體語法瑰妄。
在項目根目錄創(chuàng)建babel.config.json
{"presets": [...],"plugins": [...]}
在項目中創(chuàng)建通過創(chuàng)建.babelrc.json
{"presets": [...],"plugins": [...]}
或者直接在package.json中的babel屬性
{"babel": {"presets": [ ... ],"plugins": [ ... ],? } }
使用 CLI (@babel/cli)
npminstall --save-dev @babel/core @babel/cli
npx babel script.js--out-file script-compiled.js--source-maps
使用 API (@babel/core)
require("@babel/core").transform("code", {plugins:["@babel/plugin-transform-arrow-functions"]});
編譯過程分為三個階段:解析陷嘴、轉換和打印輸出
可以參考:https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md
結合 webpack 和 Babel 進行 JavaScript 編譯
在使用webpack進行構建時,可以使用Babel提供的babel-loader插件在webpack構建過程中的源碼轉換階段對JavaScript進行編譯间坐,使用方式同常規(guī)的webpack loader 也就是babel-loader灾挨,來看一下webpack.config.js 的配置:
// webpack.config.js{? ? module: {? ? ? ? rules: [? ? ? ? ? ? {? ? ? ? ? ? ? ? test:/\.js$/,exclude:/(node_modules|bower_components)/,? ? ? ? ? ? ? ? use: {? ? ? ? ? ? ? ? ? ? loader:'babel-loader',options: {"presets": ["es2015","stage-2"]? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ]? ? }}