babel-preset-env:一个帮你配置babel的preset

更新日期: 2018-04-10阅读: 11.7k标签: babel

babel-preset-env 一个帮你配置babel的preset,根据配置的目标环境自动采用需要的babel插件。


问题

目前,几个presets就能让你确定babel应该支持那些功能:

  • babel-preset-es2015, babel-preset-es2016等:支持不同版本的ECMAScript规范。 es2015 转译了ES6比ES5的新特性, es2016 转译了ES2016比ES6的新特性等等。
  • babel-preset-latest: 支持现有所有ECMAScript版本的新特性,包括处于stage 4里的特性(已经确定的规范,将被添加到下个年度的)。

问题是这些presets有时做的多余了,举个例子,大部分现代浏览器已经支持ES6的generators了,但是如果你设置了babel-preset-es2015,generator函数还是会被转译成复杂的ES5代码


解决方案

babel-preset-env 功能类似 babel-preset-latest,优点是它会根据目标环境选择不支持的新特性来转译。

note:实验性的属性(babel-preset-latest不支持的)需要手动安装配置相应的plugins或者presets。这样你再不需要 es20xx presets了。

浏览器

你可以选择指定相应的浏览器配置:

  • browsers参数在这里查询 browserslist . 举个例子:

    • 支持每个浏览器最近的两个版本和IE大于等于7的版本所需的polyfill和代码转译。

      "babel": {
        "presets": [
          [
            "env",
            {
              "targets": {
                "browsers": ["last 2 versions", "ie >= 7"]
              }
            }
          ]
        ]
      },
      
      
    • 支持市场份额超过5%的浏览器。

      "targets": {
        "browsers": "> 5%"
      }
      
      
  • 指定浏览器版本:

     "targets": {
       "chrome": 56
     }
    
    

Node.js

如果你通过Babel编译你的Node.js代码,babel-preset-env 很有用,设置 "targets.node" 是 "current",支持的是当前运行版本的nodejs:

"babel": {
  "presets": [
    [
      "env",
      {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
},

我的GitHub上有个测试node参数的例子,请参考 async-iter-demo.


其他配置

下面会列举 babel-preset-env部分常用配置。所有配置请查看点击 env preset; 中文版本

modules (string, 默认值: "commonjs")

将ES6模块语法转换为另一种模块类型,可选值:

  • 各种流行的模块化规范:"amd"、 "commonjs"、 "systemjs"、 "umd"
  • 禁止转译:false

include, exclude (Array of strings, 默认值: [])

  • include 必须要转译的功能 (比如 覆盖有故障的本地功能)。跟单独启用相应插件是一样的。
  • exclude 禁止转译的功能。

useBuiltIns (boolean, 默认值: false)

babel为标准库中的新功能提供了polyfill,为内置对象,静态方法,实例方法,生成器函数提供支持。 babel-preset-env可以实现基于特定环境引入需要的polyfill。

两种使用方法:

  • core-js, 根据需要引入ES5,ES6+标准方法的实现。
    • 安装 polyfill: npm install core-js --save
    • 引入 polyfill: import "core-js";
  • babel-polyfill 包含core-js 和regenerate-runtime (提供 async 语法编译后的运行时环境)。
    • 安装 polyfill: npm install babel-polyfill --save
    • 引入 polyfill: import "babel-polyfill";

两种方法最终都会根据环境转译成特定的polyfill。 比如:

import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";
import "core-js/modules/web.timers";
import "core-js/modules/web.immediate";
import "core-js/modules/web.dom.iterable";

note:

  • 在整个应用里只能引入一次polyfill,可以在 “main” 模块里一次引入。
  • useBuiltIns 会使浏览器下载的代码变少 (最终打包的文件大小变小了)。但是不会节约内存, 因为polyfill本身只会安装缺少的部分。

更多polyfill的内容请参考《Setting up ES6》中的章节:“Babel: configuring standard library and helpers

debug (boolean, default: false)

以下内容都会用console.log输出 :

  • 目标环境
  • 启用的transforms
  • 启用的plugins
  • 启用的polyfills

尝试下面的示例,瞧瞧console输出。

举例

下面的例子选自preset的readme文件:

{
  "presets": [
    [ "env", {
      "targets": {
        "safari": 10
      },
      "modules": false,
      "useBuiltIns": true,
      "debug": true
    }]
  ]
}

模块不会被转译,可以将imports和exports让webpack去处理。

debug 的输出如下:

Using targets:
{
  "safari": 10
}

Modules transform: false

Using plugins:
  transform-exponentiation-operator {}
  transform-async-to-generator {}

Using polyfills:
  es7.object.values {}
  es7.object.entries {}
  es7.object.get-own-property-descriptors {}
  web.timers {}
  web.immediate {}
  web.dom.iterable {}


env是如何基于目标环境去匹配哪些是需要转译的?

根据以下外部数据来确定目标环境支持的情况,可以定期执行build-data.js 来生成 plugins.json

下一步还能做什么?

有可以访问‘环境’ 的插件

未来计划让插件拥有检查当前环境具有什么可能性的能力,两个好处:

  • 一些plugins (比如对象扩展运算符) 目前通过选项告诉他们是否使用本地功能或polyfills。如果能知道当前 “环境”,就不需要配置了。

  • 基于babel的minifiers可以确定是否可以输出。比如,箭头函数。

简化presets

  • 基于ECMAScript版本的Presets (es2015 等)很多已经过时了 。Babel团队考虑会在未来的版本中移除他们 (比如, 通过废弃处理)。

  • 基于TC39不同阶段的提案的Presets (stage-0,1,2,3等) 也是去除的候选,因为在这些statges中的标准是不断变化的。提案可以在2个月内改变。因此,直接引用一些实验性的plugins会是更好的选择。

感谢

延伸阅读


链接: https://www.fly63.com/article/detial/609

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

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

深入理解Babel原理及其使用,babel把ES6转成ES5的原理是什么?

文的babel使用场景局限于babel配合webpack来转译输出es5的js代码,babel的命令行、以代码形式调用或node环境下这些统统都不会涉及。Babel使用的难点主要在于理解polyfill、runtime和core-js。

ES6之Babel的各种坑总结【转载】

自从 Babel 由版本5升级到版本6后,在安装和使用方式上与之前大相径庭,于是写了这篇入坑须知,以免被新版本所坑。坑一本地安装和全局安装 、坑二编译插件、坑三babel-polyfill插件

babel-polyfill使用与性能优化

本文主要内容包括:什么是babel-polyfill,如何使用,如何通过按需加载进行性能优化。babel只负责语法转换,比如将ES6的语法转换成ES5。但如果有些对象、方法,浏览器本身不支持,此时需要引入babel-polyfill来模拟实现这些对象、方法。

babel的初步了解

由于现在前端出现了很多非es5的语法,如jsx,.vue,ts等等的格式和写法。babel其实是一个解释器,它主要讲进行中的代码分为三个阶段执行:解释,转换,生成。

深入类和继承内部原理+Babel和 TypeScript 之间转换

在 JavaScript 中,没有基本类型,创建的所有东西都是对象。例如,创建一个新字符串,与其他语言不同,在 JavaScript 中,字符串或数字的声明会自动创建一个封装值的对象,并提供不同的方法,甚至可以在基本类型上执行这些方法。

使用 Webpack 与 Babel 配置 ES6 开发环境

在项目根目录下新建一个配置文件—— webpack.config.js 文件:执行编译打包命令,完成后打开 bundle.js 文件发现 isNull 和 unique 两个函数没有被编译,和 webpack 官方说法一致:webpack 默认支持 ES6 模块语法,要编译 ES6 代码依然需要 babel 编译器。

Babel_如何写一个Babel插件

Babel对代码进行转换,会将JS代码转换为AST抽象语法树(解析),对树进行静态分析(转换),然后再将语法树转换为JS代码(生成)。每一层树被称为节点。每一层节点都会有type属性,用来描述节点的类型。其他属性用来进一步描述节点的类型。

初学 Babel 工作原理

Babel 对于前端开发者来说应该是很熟悉了,日常开发中基本上是离不开它的。我们已经能够熟练地使用 es2015+ 的语法。但是对于浏览器来说,可能和它们还不够熟悉,我们得让浏览器理解它们,这就需要 Babel

Babel是什么?

Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。下面列出的是 Babel 能为你做的事情

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!