ES2015/ES2016/ES2017等新語法,新API的出現讓前端寫起來更爽,更不用說考慮到面向將來編碼。可咱們使用這些新語法,新API,代碼的運行兼容性勢必受到影響。babel的適時出現,解決了咱們使用next generation JavaScript的顧慮!它多是咱們最常使用的JavaScript轉碼工具了,但是你真的瞭解它的使用了嗎?前端
TC39是ECMAScript規範的設計制定組織,它的成員包含主流瀏覽器廠商,它實際推進着JavaScript語言的發展的。咱們知道,ECMAScript是規範,而JavaScript語言是參照ECMAScript規範的實現。node
1997年,產出ECMAScript。原由是1996年末,Netscape公司將JavaScript提交給ECMA International組織對JavaScript語言進行標準化。webpack
1998年,發佈ECMAScript2git
1999年,發佈ECMAScript3,成爲JavaScript的通行標準,獲得了各瀏覽器廠商的普遍支持。web
2009年,發佈ECMAScript5,其間,ECMAScript4由於改版過於激進,中途夭折。npm
2015年,ECMAScript6發佈,也稱爲ES2015,ES.Harmonyjson
2016年,ECMAScript7發佈,也稱爲ES2016,ES.Nextpromise
2017年,ECMAScript8發佈,也稱爲ES2017瀏覽器
TC39 Process規定了每項新特性歸入規範的過程,分爲5個階段babel
stage0: strawman,能夠理解成idea迸發
stage1: proposal,也就是書面化產出一個提案
stage2: draft,產出規範的草案
stage3: candidate,該特性進入候選階段
stage4: finished,會盡快隨版正式發佈
將來,按約定每一年會繼續發佈一個版本,貌似也預示着JavaScript社區的活躍。語言規範迭代這麼快,對老版本瀏覽器的支持這項光榮而偉大的任務就交給了babel。
babel轉碼器,提供轉碼API,babel-core雖然經常使用,但平常開發不多直接調用,webpack中使用babel-loader加載js,babel-loader其實會直接調用babel-core API對文件進行轉碼。
babel.transform(code: string, options?: Object) babel.transformFile(filename: string, options?: Object, callback: Function) babel.transformFileSync(filename: string, options?: Object) babel.transformFromAst(ast: Object, code?: string, options?: Object)
主要用於babel轉碼的命令行調用,前端項目基本已經離不開webpack,因此babel-cli常常用於node項目中的build,由於咱們可能會寫async/await,但咱們的服務端環境是V6.x
babel app --out-dir webapp
babel默認只作轉碼,ployfill的工做(好比一些新內置對象、新的靜態方法、實例方法),須要在運行入口引人babel-polyfill來支持,爲運行環境提供墊片支持。
須要polyfill: module.exports = { builtins: { Symbol: "symbol", Promise: "promise", Map: "map", WeakMap: "weak-map", Set: "set", WeakSet: "weak-set", Observable: "observable", setImmediate: "set-immediate", clearImmediate: "clear-immediate", asap: "asap" //parseFloat: "parse-float", // temporary disabled //parseInt: "parse-int" // temporary disabled }, methods: { Array: { concat: "array/concat", // deprecated copyWithin: "array/copy-within", entries: "array/entries", every: "array/every", fill: "array/fill", filter: "array/filter", findIndex: "array/find-index", find: "array/find", forEach: "array/for-each", from: "array/from", includes: "array/includes", indexOf: "array/index-of", //isArray: "array/is-array", // temporary disabled join: "array/join", keys: "array/keys", lastIndexOf: "array/last-index-of", map: "array/map", of: "array/of", pop: "array/pop", // deprecated push: "array/push", // deprecated reduceRight: "array/reduce-right", reduce: "array/reduce", reverse: "array/reverse", // deprecated shift: "array/shift", // deprecated slice: "array/slice", // deprecated some: "array/some", sort: "array/sort", splice: "array/splice", unshift: "array/unshift", // deprecated values: "array/values" }, JSON: { stringify: "json/stringify" }, Object: { assign: "object/assign", create: "object/create", defineProperties: "object/define-properties", defineProperty: "object/define-property", entries: "object/entries", freeze: "object/freeze", getOwnPropertyDescriptor: "object/get-own-property-descriptor", getOwnPropertyDescriptors: "object/get-own-property-descriptors", getOwnPropertyNames: "object/get-own-property-names", getOwnPropertySymbols: "object/get-own-property-symbols", getPrototypeOf: "object/get-prototype-of", isExtensible: "object/is-extensible", isFrozen: "object/is-frozen", isSealed: "object/is-sealed", is: "object/is", keys: "object/keys", preventExtensions: "object/prevent-extensions", seal: "object/seal", setPrototypeOf: "object/set-prototype-of", values: "object/values" }, RegExp: { escape: "regexp/escape" // deprecated }, Math: { acosh: "math/acosh", asinh: "math/asinh", atanh: "math/atanh", cbrt: "math/cbrt", clz32: "math/clz32", cosh: "math/cosh", expm1: "math/expm1", fround: "math/fround", hypot: "math/hypot", imul: "math/imul", log10: "math/log10", log1p: "math/log1p", log2: "math/log2", sign: "math/sign", sinh: "math/sinh", tanh: "math/tanh", trunc: "math/trunc", iaddh: "math/iaddh", isubh: "math/isubh", imulh: "math/imulh", umulh: "math/umulh" }, Symbol: { for: "symbol/for", hasInstance: "symbol/has-instance", isConcatSpreadable: "symbol/is-concat-spreadable", iterator: "symbol/iterator", keyFor: "symbol/key-for", match: "symbol/match", replace: "symbol/replace", search: "symbol/search", species: "symbol/species", split: "symbol/split", toPrimitive: "symbol/to-primitive", toStringTag: "symbol/to-string-tag", unscopables: "symbol/unscopables" }, String: { at: "string/at", codePointAt: "string/code-point-at", endsWith: "string/ends-with", fromCodePoint: "string/from-code-point", includes: "string/includes", matchAll: "string/match-all", padLeft: "string/pad-left", // deprecated padRight: "string/pad-right", // deprecated padStart: "string/pad-start", padEnd: "string/pad-end", raw: "string/raw", repeat: "string/repeat", startsWith: "string/starts-with", trim: "string/trim", trimLeft: "string/trim-left", trimRight: "string/trim-right", trimStart: "string/trim-start", trimEnd: "string/trim-end" }, Number: { EPSILON: "number/epsilon", isFinite: "number/is-finite", isInteger: "number/is-integer", isNaN: "number/is-nan", isSafeInteger: "number/is-safe-integer", MAX_SAFE_INTEGER: "number/max-safe-integer", MIN_SAFE_INTEGER: "number/min-safe-integer", parseFloat: "number/parse-float", parseInt: "number/parse-int" }, Reflect: { apply: "reflect/apply", construct: "reflect/construct", defineProperty: "reflect/define-property", deleteProperty: "reflect/delete-property", enumerate: "reflect/enumerate", // deprecated getOwnPropertyDescriptor: "reflect/get-own-property-descriptor", getPrototypeOf: "reflect/get-prototype-of", get: "reflect/get", has: "reflect/has", isExtensible: "reflect/is-extensible", ownKeys: "reflect/own-keys", preventExtensions: "reflect/prevent-extensions", setPrototypeOf: "reflect/set-prototype-of", set: "reflect/set", defineMetadata: "reflect/define-metadata", deleteMetadata: "reflect/delete-metadata", getMetadata: "reflect/get-metadata", getMetadataKeys: "reflect/get-metadata-keys", getOwnMetadata: "reflect/get-own-metadata", getOwnMetadataKeys: "reflect/get-own-metadata-keys", hasMetadata: "reflect/has-metadata", hasOwnMetadata: "reflect/has-own-metadata", metadata: "reflect/metadata" }, System: { global: "system/global" }, Error: { isError: "error/is-error" // deprecated }, Date: { //now: "date/now" // temporary disabled }, Function: { // Warning: /virtual/ method - prototype, not static, version //bind: "function/virtual/bind" // temporary disabled } } };
引人後,require
方法會被重寫並綁定一個hook到babel的complier,也就是說當再次經過require
加載其餘腳本文件時會在運行時自動經過babel轉碼之。不適用與生產環境。
require('require-register'); const file = require('file.es'); // 引用的文件會在運行時自動轉碼
經過在.babelrc文件中指定轉碼plugin,babel才能達到指定特性的轉碼效果。
{ plugins: [ 'transform-es2015-arrow-functions', 'transform-es2015-block-scoped-functions' ] }
一個一個plugin添加可能很麻煩?babel提供了preset
,它能夠理解爲plugin的組合,你能夠這樣建立一個preset:
爲你的preset建立一個git倉庫,好比babel-preset-mynamepreset
git clone <倉庫地址>
目錄結構很簡單,以下
編輯index.js
發佈到npm倉庫
// 目錄結構 - package.json | - src |-- index.js
// index.js import arrowFunctions from "babel-plugin-transform-es2015-arrow-functions"; import blockScopedFunctions from "babel-plugin-transform-es2015-block-scoped-functions"; export default { plugins: [ arrowFunctions, blockScopedFunctions ] };
固然,社區有相對更成熟的presets,能夠直接引用, 好比
babel-preset-es2015
babel-preset-stage-0
babel-preset-stage-1
babel-preset-stage-2
babel-preset-stage-3
babel-preset-es2016
babel-preset-es2017
babel-preset-latest
...
能夠按需選擇使用~