美文网首页程序员
前端工程搭建入门(六)支持es6新特性

前端工程搭建入门(六)支持es6新特性

作者: 文者字清 | 来源:发表于2018-08-05 11:26 被阅读0次

    背景

    • 因为es6发布较晚,各大浏览器还没完全支持es6语法以及其特性,现阶段开发者大多采用babel进行代码语法转换

      Babel has support for the latest version of JavaScript through syntax transformers. These plugins allow you to use new syntax, right now without waiting for browser support.
      Babel通过语法变换器支持最新版本的JavaScript。 这些插件允许您立即使用新语法,而无需等待浏览器支持。

    • 但是 babel 只是转换语法,并不能转换新特性,如箭头函数以及一些新的方法拓展

      Since Babel only transforms syntax (like arrow functions), you can use babel-polyfill in order to support new globals such as Promise or new native methods like String.padStart (left-pad). It uses core-js and regenerator.
      由于Babel只转换语法(如箭头函数),因此您可以使用babel-polyfill来支持新的全局变量(如Promise)或新的本机方法(如String.padStart(left-pad))。 它使用core-js和regenerator。

    • 除了polyfill,还可以使用 transform-runtime 进行新特性支持。具体使用方法就不说了,文档里写的很清楚,下面就只了解一下这两种方式有什么区别。

    Polyfill

    • 安装:
      • npm install --save babel-polyfill (babel 6)
      • npm install --save @babel/polyfill (babel 7)
    • 它是怎么支持 Map Set Promise async 等全局方法的?通过一个示例来了解一下:
      1. 写了两个js文件,以便更好地了解polyfill对于多处引用是怎么处理的。
        List.js
        Detail.js
      2. 两个文件几乎一模一样,打包编译,控制台输出如下:
        console
      3. 下面看一下打包之后的代码,看看这里的 async Map includes 是来自哪里 async 解析
      4. 可以看到,getTitle 这个 async 函数是 _asyncToGenerator 生成的,看一下 _asyncToGenerator 是哪里定义的:
        _asyncToGenerator
      5. 这个转换函数一共有4个,两次定义,两次使用。List 使用了一次,定义了一次;Detail 里使用了一次,也定义了一次。接着看 includes :
        includes
      6. 很明显,polyfill 重写了数组原型所有 es6+ 新增的方法。再看 Map 是如何转换的:
        Map 定义
      7. 在这里定义了 Map ,这是一个全局变量,只定义了一次,再看 118 模块干了啥:
        118
      8. 显而易见,重写了 Map 函数。

    综上,polyfill 的原则就是,对于全局变量 Map Set Promise 等,以及 es6 新增的方法全部重写。async 是通过 Promise 实现的,并且每个出现引用的模块都会定义一次。

    transform-runtime

    • 安装(依赖 babel-runtime):
      • npm install --save-dev babel-plugin-transfrom-runtime (babel 6)
      • npm install --save babel-runtime (babel 6)
      • npm install --save-dev @babel/plugin-transfrom-runtime (babel 7)
      • npm install --save @babel/runtime (babel 7)
    • 按照上面的顺序,看一下它是怎么处理这些新特性的:
      1. async 转换:

        async
      2. 和 polyfill 是一样的原理,哪里引用,哪里定义。再看 includes,找了一大圈也没找到定义的地方,说明 transform-runtime 并没有对 includes 处理,官方文档说了,"foobar".includes("foo")这种实例方法是不会被转换的,也就是完全靠浏览器去支持了,如果浏览器不支持,就需要使用 polyfill ,所以这算是 transform-runtime 的小缺陷。

      3. 再看 Map ,同样,找了一圈未果,没有找到定义的地方,再看文档,完美解答了我的困惑:

    The runtime transformer plugin does three things:

    • Automatically requires babel-runtime/regenerator when you use generators/async functions.
    • Automatically requires babel-runtime/core-js and maps ES6 static methods and built-ins.
    • Removes the inline Babel helpers and uses the module babel-runtime/helpers instead.
      What does this actually mean though? Basically, you can use built-ins such as Promise, Set, Symbol, etc., as well use all the Babel features that require a polyfill seamlessly, without global pollution, making it extremely suitable for libraries.

    runtime 编译器插件做了以下三件事:

    • 当你使用 generators/async 函数时,自动引入 babel-runtime/regenerator 。
    • 自动引入 babel-runtime/core-js 并映射 ES6 静态方法和内置插件。
    • 移除内联的 Babel helper 并使用模块 babel-runtime/helpers 代替。
      这意味着什么?基本上,你可以使用诸如 Promise,Set,Symbol 等内置函数,以及所有需要 polyfill 来完成且不带来全局污染的 Babel 功能,因此非常适合作为库使用。

    综上,transform-runtime 不会污染全局环境,不会污染原型,至于文档说的 沙盒环境 ,暂时没感受到,希望以后的开发过程中能够体会到其真正用意。

    这些就是我一步一步去仔细体会 polyfill 和 transform-runtime 的一些区别,当然只是通过一个简单的列子,不能展现所有的实现原理,只是感受二者的基本差异。可能有错误的理解,希望大家多多指正,共同学习,共同进步 。

    相关文章

      网友评论

        本文标题:前端工程搭建入门(六)支持es6新特性

        本文链接:https://www.haomeiwen.com/subject/hvbqvftx.html