babel 学习(未完待续)

164 阅读4分钟

1).babelrc

  babel.config.js并不是.babelrc的替代品,.babelrc文件用于局部配置(如下代码所示),可放置于所有目录中。如果当前目录没有.babelrc文件,那么就会往上查找直至找到为止。

插件

Babel的编译可分为三个阶段:

  1. 解析:通过parser将代码字符串解析成抽象语法树(AST)。
  2. 转换:对抽象语法树进行转换操作,插件应用于  babel 的转译过程,尤其是第二个阶段  Transformation,如果这个阶段不使用任何插件,那么  babel 会原样输出代码。
  3. 生成 : 根据变换后的抽象语法树再生成代码字符串(用  babel-generator 通过 AST 树生成 ES5 代码。)。(参考

而插件(Plugin)在转换过程中起到了至关重要的作用。借助Babel的插件可将解析完成的AST按照特定的要求进行处理,然后再输出生成的代码。

1)插件类型

  Babel中的插件分为两种类型:语法和转换。语法插件只允许Babel解析成特定类型的语法,例如JSX、Flow等。转换插件常用来编译ES6、ES7、React和Modules等,由于能自动开启相应的语法插件,因此不用显式的指定两种插件。

2)执行顺序

  插件的执行顺序会受配置时所处的位置的影响,具体规则如下所列,其中预设是指官方预先设计的一组插件集,本质上仍然是插件。

(1)插件执行在预设之前。

(2)插件会按顺序从前往后执行。

(3)预设与插件相反,从后往前执行。

  以下面的配置信息为例,在插件中,先执行@babel/plugin-transform-arrow-functions,后执行@babel/plugin-transform-classes。而在预设中,先执行@babel/preset-react,后执行@babel/preset-env。

{
  "plugins": ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-classes"],
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

3)插件参数

  如果要配置插件的参数,那么得在插件名称后增加一个参数对象,并且写成数组的形式,如下所示。

{
  "plugins": [
    ["@babel/plugin-transform-arrow-functions", { "spec": true }], 
    ["@babel/plugin-transform-classes", { "loose": true }]
  ]
}

  预设也能接收参数,其写法与之类似。

预设

  如果在配置文件中一个一个的声明插件,那么不仅会让该文件变得巨大,而且还难免会有所遗漏。官方为了避免此类问题,引入了预设(Preset)的概念。预设类似于生活中的套餐,每个套餐会集合不同的插件,从而能够一次性安装各类插件,并且还可共享配置的参数。

1)@babel/preset-env

  此预设不仅集合了最新的ES语法(即编译指定的ES标准,presets 是 plugins 的集合,把很多需要转换的ES6的语法插件集合在一起,避免大家各种配置,比如``` ES6的 async,class,let),还能配置所要支持的平台(例如Node、Chrome等)和版本,以及按需加载插件,其安装命令如下所示。

npm install --save-dev @babel/preset-env

  下面是一个预设的配置示例,支持Chrome 58和IE 11,以及超过市场份额5%的浏览器。还有许多其它可供选择的配置参数,具体可翻阅官方文档

@babel/preset-react:对react语法的转换

babel-loader : webpack与Babel通信的桥梁,不处理转译

@babel/core : 核心库,让Babel识别js语法,并把js语法转换成AST抽象语法树

  • @babel/parser:用于将代码进行语法分析,词法分析,然后生成一个语法树(AST)。
  • @babel/traverse:遍历抽象语法树(AST),并调用Babel配置文件中的preset与plugin,对抽象语法树(AST)进行增删改。
  • @babel/generator:用于把上一步操作好的AST生成代码。

image.png

@babel/preset-env:将ES6语法转换成ES5语法,包含翻译的语法规则

  • presets 加载顺序和一般理解不一样 ,是倒序的,比方下面的先加载 @babel/preset-react,再加载 @babel/preset-env,这个是个历史原因的,因为作者认为大部分会把 presets 写成 ["es2015", "stage-0"],stage-x 是 Javascript 语法的一些提案,那这部分可能依赖了ES6的语法,解析的时候得先解析这部分到ES6,在把ES6解析成ES5\
{
    "presets": [
        [
            "@babel/preset-env",
             "@babel/preset-react",
        ]
    ],
    plugins": [
        "@babel/plugin-a",
        "@babel/plugin-b"
    ],
}
  • plugins 按照数组的 index 增序(从数组第一个到最后一个)进行编译。

  • plugins 优先于 presets进行编译。

参考:zhuanlan.zhihu.com/p/68286407