babel 插件的使用

插件

  1. npm install --save-dev @babel/plugin-transform-arrow-functions

    • 將箭頭函數(shù)轉(zhuǎn)換為es5
  2. 可以直接使用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)換

  3. Polyfill

    @babel/polyfill 模塊包括 core-js 和一個(gè)自定義的 regenerator runtime 模塊用于模擬完整的 ES2015+ 環(huán)境

    1. polyfill 將添加到全局范圍(global scope)和類(lèi)似 String 這樣的內(nèi)置原型(native prototypes)中。如果你不需要類(lèi)似 Array.prototype.includes 的實(shí)例方法,可以使用 transform runtime 插件而不是對(duì)全局范圍(global scope)造成污染的 @babel/polyfill。
  4. 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)境的配置

  1. .babelrc.js

    const presets = [ ... ];
    const plugins = [ ... ];
    
    if (process.env["ENV"] === "prod") {
    plugins.push(...);
    }
    
    module.exports = { presets, plugins };
    

pollyfill

  1. 每次打包的文件中有重復(fù)內(nèi)容 (比如_createClass內(nèi)容, 在每一個(gè)文件中都有, 造成資源浪費(fèi)和無(wú)法重復(fù)利用)
  2. 使用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

  1. 針對(duì)上述pollyfill無(wú)法重用, 打包文件過(guò)大的問(wèn)題

    • npm install --save @babel/runtime
    • npm install --save @babel/plugin-transform-runtime
  2. 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
  3. 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)替換
  4. transform-runtime優(yōu)點(diǎn)

    • 不會(huì)污染全局變量
    • 多次使用只會(huì)打包一次
    • 依賴(lài)統(tǒng)一按需引入,無(wú)重復(fù)引入,無(wú)多余引入
  5. 缺點(diǎn)

    • 不支持實(shí)例化的方法Array.includes(x) 就不能轉(zhuǎn)化
    • 如果使用的API用的次數(shù)不是很多,那么transform-runtime 引入polyfill的包, 會(huì)比不是transform-runtime 時(shí)大

AST 使用

  1. token, ast 可視化 http://resources.jointjs.com/demos/javascript-ast
  2. jsx-control-statements: https://github.com/AlexGilleran/jsx-control-statements
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容