插件
-
npm install --save-dev @babel/plugin-transform-arrow-functions
- 將箭頭函數(shù)轉(zhuǎn)換為es5
-
可以直接使用preset-env, 這樣就不用一個(gè)個(gè)添加插件(如上述箭頭函數(shù)轉(zhuǎn)換插件, class轉(zhuǎn)function插件等等)
- 但是同等的我們需要配置打包目標(biāo)瀏覽器
const presets = [ [ "@babel/env", { targets: { edge: "17", firefox: "60", chrome: "67", safari: "11.1", }, useBuiltIns: "usage", }, ], ];名為 env 的 preset 只會(huì)為目標(biāo)瀏覽器中沒(méi)有的功能加載轉(zhuǎn)換插件。 如果瀏覽器支持箭頭函數(shù), 那么babel就不會(huì)進(jìn)行轉(zhuǎn)換
-
Polyfill
@babel/polyfill 模塊包括 core-js 和一個(gè)自定義的 regenerator runtime 模塊用于模擬完整的 ES2015+ 環(huán)境
- polyfill 將添加到全局范圍(global scope)和類(lèi)似 String 這樣的內(nèi)置原型(native prototypes)中。如果你不需要類(lèi)似 Array.prototype.includes 的實(shí)例方法,可以使用 transform runtime 插件而不是對(duì)全局范圍(global scope)造成污染的 @babel/polyfill。
-
1.babel.js 測(cè)試輸出后代碼 (node ./src/1.babel.test.js)
const babel = require("@babel/core"); const presets = [ [ "@babel/env", { targets: { // 1. 將這里的chrome:67 版本換成30后測(cè)試看看 chrome: "60", // test_2: 測(cè)試pollyfill edge: "17", }, // test_2: 如果沒(méi)有下面這句話(huà), 那么就不會(huì)引用pollyfill, 對(duì)于無(wú)法編譯的 就不使用babel編譯 // useBuiltIns: "usage", }, ], ]; const plugins = [ '@babel/plugin-transform-arrow-functions' ] const babelConfig = { presets, plugins, }; const code = ` class Person { constructor(name) { this.name } say() { console.log('hello' + this.name) } } const func = ()=> { console.log('arrow function'); } new Person('Feng').say(); // 需要使用 pollyfill Promise.resolve().finally(); `; const result = babel.transform(code, babelConfig); console.log(result.code);"use strict"; require("core-js/modules/es6.promise"); require("core-js/modules/es6.object.to-string"); require("core-js/modules/es7.promise.finally"); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var Person = /*#__PURE__*/ function () { function Person(name) { _classCallCheck(this, Person); this.name; } _createClass(Person, [{ key: "say", value: function say() { console.log('hello' + this.name); } }]); return Person; }(); new Person('Feng').say(); // 需要使用 pollyfill Promise.resolve().finally();- 因?yàn)闉g覽器chrome版本是30, 所以使用pollyfill進(jìn)行兼容, 所以前面的幾處require引用是pollyfill的修補(bǔ)方案
- 如果將chrome版本改為60, 則會(huì)只有pollyfill promise.finally的引用
基于進(jìn)程環(huán)境的配置
-
.babelrc.js
const presets = [ ... ]; const plugins = [ ... ]; if (process.env["ENV"] === "prod") { plugins.push(...); } module.exports = { presets, plugins };
pollyfill
- 每次打包的文件中有重復(fù)內(nèi)容 (比如_createClass內(nèi)容, 在每一個(gè)文件中都有, 造成資源浪費(fèi)和無(wú)法重復(fù)利用)
- 使用pollyfill
const presets = [ [ "@babel/env", { targets: { // 1. 將這里的chrome:67 版本換成30后測(cè)試看看 chrome: "60", // test_2: 測(cè)試pollyfill edge: "17", }, // test_2: 如果沒(méi)有下面這句話(huà), 那么就不會(huì)引用pollyfill, 對(duì)于無(wú)法編譯的就不使用babel編譯 useBuiltIns: "usage", }, ], ];
transform-runtime
-
針對(duì)上述pollyfill無(wú)法重用, 打包文件過(guò)大的問(wèn)題
- npm install --save @babel/runtime
- npm install --save @babel/plugin-transform-runtime
-
babel-runtime和 babel-plugin-transform-runtime的區(qū)別是,
- 相當(dāng)一前者是手動(dòng)擋而后者是自動(dòng)擋,每當(dāng)要轉(zhuǎn)譯一個(gè)api時(shí)都要手動(dòng)加上require('babel-runtime'),
- 而babel-plugin-transform-runtime會(huì)由工具自動(dòng)添加,主要的功能是為api提供沙箱的墊片方案,不會(huì)污染全局的api,因此適合用在第三方的開(kāi)發(fā)產(chǎn)品中。
- babel-transform-runtime進(jìn)行polyfill的包就是在babel-runtime這個(gè)包里, core-js 、regenerator等 poiiyfill
-
runtime轉(zhuǎn)換器插件主要做了三件事:
- 當(dāng)你使用generators/async方法、函數(shù)時(shí)自動(dòng)調(diào)用babel-runtime/regenerator
- 當(dāng)你使用ES6 的Map或者內(nèi)置的東西時(shí)自動(dòng)調(diào)用babel-runtime/core-js
- 移除內(nèi)聯(lián)babel helpers并替換使用babel-runtime/helpers來(lái)替換
-
transform-runtime優(yōu)點(diǎn)
- 不會(huì)污染全局變量
- 多次使用只會(huì)打包一次
- 依賴(lài)統(tǒng)一按需引入,無(wú)重復(fù)引入,無(wú)多余引入
-
缺點(diǎn)
- 不支持實(shí)例化的方法Array.includes(x) 就不能轉(zhuǎn)化
- 如果使用的API用的次數(shù)不是很多,那么transform-runtime 引入polyfill的包, 會(huì)比不是transform-runtime 時(shí)大
AST 使用
- token, ast 可視化 http://resources.jointjs.com/demos/javascript-ast
- jsx-control-statements: https://github.com/AlexGilleran/jsx-control-statements