Babel中的stage-0,stage-1,stage-2以及stage-3的作用(转)

人人知道,将ES6代码编译为ES5时,我们常用到Babel这个编译工具。人人参考一些网上的文章或者官方文档,内里常会建议人人在.babelrc中输入如下代码:  { "presets": [ "es2015",...

人人知道,将ES6代码编译为ES5时,我们常用到Babel这个编译工具。人人参考一些网上的文章或者官方文档,内里常会建议人人在.babelrc中输入如下代码: 

{
    "presets": [
      "es2015",
      "react",
      "stage-0"
    ],
    "plugins": []
  }

我们现在来说明下这个配置文件是什么意思。首先,这个配置文件是针对babel 6的。Babel 6做了一系列模块化,不像Babel 5一样把所有的内容都加载。好比需要编译ES6,我们需要设置presets为"es2015",也就是预先加载es6编译的相关模块,若是需要编译jsx,需要预先加载"react"这个模块。那问题来了,这个"stage-0"又代表什么呢? 有了"react-0",是否又有诸如"stage-1", "stage-2"等等呢?


事实上, ”stage-0"是对ES7一些提案的支持,Babel通过插件的方式引入,让Babel可以编译ES7代码。固然由于ES7没有定下来,以是这些功效随时肯能被废弃掉的。现在我们来逐一剖析内里都有什么。

 

1. 法力无边的stage-0

为什么说“stage-0” 法力无边呢,由于它包罗stage-1, stage-2以及stage-3的所有功效,同时还另外支持如下两个功效插件:

transform-do-expressions,transform-function-bind

用过React的同砚可能知道,jsx对条件表达式支持的不是太好,你不能很利便的使用if/else表达式,要么你使用三米表达,要么用函数。例如你不能写如下的代码:

var App = React.createClass({

    render(){
        let { color } = this.props;

        return (
            <div className="parents">
                {
                    if(color == 'blue') { 
                        <BlueComponent/>; 
                    }else if(color == 'red') { 
                        <RedComponent/>; 
                    }else { 
                        <GreenComponent/>; }
                    }
                }
            </div>
        )
    }
})

在React中你只能写成这样: 

var App = React.createClass({

    render(){
        let { color } = this.props;


        const getColoredComponent = color => {
            if(color === 'blue') { return <BlueComponent/>; }
            if(color === 'red') { return <RedComponent/>; }
            if(color === 'green') { return <GreenComponent/>; }
        }


        return (
            <div className="parents">
                { getColoredComponent(color) }
            </div>
        )
    }
})

 transform-do-expressions 这个插件就是为了利便在 jsx写if/else表达式而提出的,我们可以重写下代码。

var App = React.createClass({
    render(){
        let { color } = this.props;
        return (
            <div className="parents">
                {do {
                    if(color == 'blue') { 
                        <BlueComponent/>; 
                    }else if(color == 'red') { 
                        <RedComponent/>; 
                    }else { 
                        <GreenComponent/>; }
                    }
                }}
            </div>
        )
    }
})

再说说 transform-function-bind, 这个插件实在就是提供过 :: 这个操作符来利便快速切换上下文, 如下面的代码: 

obj::func
// is equivalent to:
func.bind(obj)

obj::func(val)
// is equivalent to:
func.call(obj, val)

::obj.func(val)
// is equivalent to:
func.call(obj, val)

// 再来一个复杂点的样例

const box = {
  weight: 2,
  getWeight() { return this.weight; },
};

const { getWeight } = box;

console.log(box.getWeight()); // prints '2'

const bigBox = { weight: 10 };
console.log(bigBox::getWeight()); // prints '10'

// Can be chained:
function add(val) { return this + val; }

console.log(bigBox::getWeight()::add(5)); // prints '15'

若是想更屌点,还可以写出更牛逼的代码: 

const { map, filter } = Array.prototype;

let sslUrls = document.querySelectorAll('a')
                ::map(node => node.href)
                ::filter(href => href.substring(0, 5) === 'https');
console.log(sslUrls);


2. 一应俱全的stage-1

stage-1除了包罗stage-2和stage-3,还包罗了下面4个插件:

  • transform-class-constructor-call (Deprecated)
  • transform-class-properties
  • transform-decorators – disabled pending proposal update
  • transform-export-extensions

今天就到这里了,改天我们接着剖析下"stage-2"和"stage-3", 它们又有什么新的特征呢,让我们拭目以待吧。

 

 

3.深藏不露的stage-2

为什么说stage-2深藏不露呢,由于它很低调,低调到你可以忽略它,但事实上,它很有内在的。它除了笼罩stage-3的所有功效,还支持如下两个插件:

  • syntax-trailing-function-commas
  • transform-object-reset-spread

syntax-trailing-function-commas

这个插件让人一看以为挺没趣的,让人甚至以为它有点鸡肋。因它不是对ES6功效的增添,而是为了增强代码的可读性和可修改性而提出的。如下面的代码所示:

// 假设有如下的一个函数,它有两个参数
function clownPuppiesEverywhere(
  param1,
  param2
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
  'bar'
);

// 有一天,它需要酿成3个参数,你需要这样修改
function clownPuppiesEverywhere(
  param1,
- param2
+ param2, // 这一行得加一个逗号
+ param3  // 增添参数param3
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
- 'bar'
+ 'bar', // 这里的修改为逗号
+ 'baz'  // 增添新的参数
);

// 看到没? 我们修改了4行代码。。啊啊。修改了4行代码。

修改了4行代码,嗯嗯嗯。。追求高效的程序猿想想了,以后若是有更多参数了,我是不是要改等多行,得想想,代码改的越少越好,于是有了下面的改动。。

// 我们来重新界说一下函数
function clownPuppiesEverywhere(
  param1,
  param2, // 注重这里,我们加了一个逗号哟
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
  'bar', // 这里我们也加了一个逗号
);

// 现在函数需要三个参数,我们来修改下
function clownPuppiesEverywhere(
  param1,
  param2,
+ param3, // 增添params3参数
) { /* ... */ }

clownPuppiesEverywhere(
  'foo',
  'bar',
+ 'baz', // 增添第三个参数
);

// 叮叮当,我们只修改了两行代码就完成了,好开森

说实话吧,这个功效让人有点很无语。不外程序猿对清洁代码的追求真的很让人感动,照样值得激励的。这个就是stage-2中"尾逗号函数”功效。哈哈哈哈。

transform-object-rest-spread

再来说transform-object-rest-spread, 实在它是对 ES6中解构赋值的一个扩展,由于ES6只支持对数组的解构赋值,对对象是不支持的。如下面的代码所示:

// 获取剩下的属性

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }

// 属性睁开
let n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }


4.大放异彩的stage3

为啥说stage3大放异彩呢?由于它支持赫赫有名的async和await, 这两个哥们可是解决(Ajax)回调函数的最终解决方法呀!管你什么异步,我都可以用同步的头脑来写,ES7内里异常强悍的存在。总的来说,它包罗如下两个插件:

  • transform-async-to-generator
  • transform-exponentiation-operator

transform-async-to-generator

transform-async-to-generator主要用来支持ES7中的async和await, 我们可以写出下面的代码:

const sleep = (timeout)=>{
    return new Promise( (resolve, reject)=>{
        setTimeout(resolve, timeout)
    })
}

(async ()=>{
    console.time("async");
    await sleep(3000);
    console.timeEnd("async");
})()

再来一个现实点的例子

const fetchUsers = (user)=>{
    return window.fetch(`https://api.douban.com/v2/user/${user}`).then( res=>res.json())
}


const getUser = async (user) =>{
    let users = await fetchUsers(user);
    console.log( users);
}

console.log( getUser("flyingzl"))

提醒: 由于asycn和await是ES7内里的内容,现阶段不建议使用。为了顺遂运行上面的代码,建议用webpack举行编译。

transform-exponentiation-operator

transform-exponentiation-operator这个插件算是一个语法糖,可以通过**这个符号来举行幂操作,想当于Math.pow(a,b)。如下面的样例

// x ** y

let squared = 2 ** 2;
// 相当于: 2 * 2

let cubed = 2 ** 3;
// 相当于: 2 * 2 * 2


// x **= y

let a = 2;
a **= 2;
// 相当于: a = a * a;

let b = 3;
b **= 3;
// 相当于: b = b * b * b;

很简单也很适用吧,哈。使用起来照样蛮利便的。


总结

通过以上的两篇文章,我们领会了stage-0,state-1,stage-2以及stage-3的区别。在举行现实开发时,可以更具需要来设置对应的stage。若是省事懒得折腾,一样平常设置为stage-0即可。若是为了防止开发人员使用某些太新的功效,我们可以限制到某个特定的stage即可。若是有其他问题,迎接人人留言 :-)。 更详细的请参考https://babeljs.io/docs/plugins/preset-stage-0/

 

 

思源资源网:分类流动

1.阿里云: 本站现在使用的是阿里云主机,平安/可靠/稳固。点击领取2000米代金券、领会最新阿里云产物的种种优惠流动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各种产物的最新流动,优惠券领取点击进入

3.广告同盟: 整理了现在主流的广告同盟平台,若是你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/186

  • 发表于 2021-02-23 09:18
  • 阅读 ( 298 )
  • 分类:互联网

0 条评论

请先 登录 后评论
杨这更
杨这更

681 篇文章

你可能感兴趣的文章

相关问题