当前位置: 首页 > 工具软件 > Project Babel > 使用案例 >

babel文档

万德海
2023-12-01

前端技术之webpack(3.10.0)
————babel
V1.0

https://doc.webpack-china.org/

https://github.com/webpack/webpack

1 babel

babel的基本概念

babel是前端的一个生态系统,babel的核心功能 是将ES6代码 -> 可兼容的ES5代码

    ES6语法 + API  谷歌支持程度差不多达到99%

    ES6语法 + API  IE支持程度差不多达到9%

babel: 兼容性到达70%

Ø @babel/core

     可以看做 babel 的编译器。babel 的核心 api 都在这里面,比如 transform,

    主要都是处理转码的。它会把我们的 js 代码,抽象成 ast,即 abstract syntax tree 的 缩写,
    是源代码的抽象语法结构的树状表现形式。我们可以理解为,它定义的一种 分析 js 语法的树状结构。
    也就是说 es6 的新语法,跟老语法是不一样的,那我们 怎么去定义这个语法呢。所以必须要先转成 ast,
    去发现这个语法的 kind,分别做 对应的处理,才能转化成 es5.

Ø @babel/cli

     @babel/cli 是 babel 提供的命令行工具,用于命令行下编译源代码。

    这里假定我们已通过 npm init 初始化项目。

    首先,在项目中安装 @babel/cli:

         npm install --save-dev @babel/core @babel/cli

    如果你用过 babel 6,可能要问,怎么不是 npm install --save-dev babel-cli?@ 符号 又是什么?
    这是 babel 7 的一大调整,原来的 babel-xx 包统一迁移到babel 域下 - 域由 @ 符号来标识,

        一来便于区别官方与非官方的包,二来避免可能的包命名冲突。

    现在假定我们的项目下有一个 script.js 文件,内容是:

        let fun = () => console.log('hello babel.js')

        我们试试运行

            npx babel script.js

        结果:

            let fun = () => console.log('hello babel.js');

        问题:

            还是原来的代码,没有任何变化。说好的编译呢?

                这个调整则是在 babel 6 里发生的。Babel 6 做了大量模块化的工作,

                将原来集成一体的各种编译功能分离出去,独立成插件。

                这意味着,默认情况下,当下版本的 babel 不会编译代码。我们需 要安装各式各样的插件

Ø .babelrc

随着各种新插件的加入,我们的命令行参数会越来越长。

这时,我们可以新建一个 .babelrc 文件,把各种命令行参数统一到其中。

比如,要配置前面提到过的箭头函数插件:

 {

   "plugins": ["@babel/plugin-transform-arrow-functions"]

 }

之后,在命令行只要运行 npx babel script.js 即可,babel 会自动读取 .babelrc 里的配 置并应用到编译中:

 $ npx babel script.js

 let fun = function () {

   return console.log('hello babel.js');

 };

Ø babel 套餐

@babel/preset-env

 假如我们现在有一个项目,页面要求支持 IE 10,但 IE 10 不支持箭头函数、 class 及 const,
 可是你喜欢用这些新增的 JavaScript 语法,你在项目里写了这么 一段代码:

     const alertMe = (msg) => {

       window.alert(msg)

     }

     class Robot {

       constructor (msg) {

         this.message = msg

       }

       say () {

         alertMe(this.message)

       }

     }

     const marvin = new Robot('hello babel')

     显然,在 IE 10 下这段代码报错了。

     好消息是,babel 有各种插件满足你的上述需求。我们来安装相应插件:

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

         @babel/plugin-transform-block-scoping @babel/plugin-transform-classes

     接着,将它们加入 .babelrc 配置文件中:

         {

           "plugins": [

             "@babel/plugin-transform-arrow-functions",

             "@babel/plugin-transform-block-scoping",

             "@babel/plugin-transform-classes"

             ]

         }

    然后运行 npx babel script.js,就有编译结果了。

    问题:

        这样安装插件、配置 .babelrc 的过程非常乏味,而且容易出错。通常,我们 不会关心到具体的某个

        ES2015 特性支持情况这个层面,我们更关心浏览器版本这个层面。我不想关 心 babel 插件的配置,我只希望,
        给 babel 一个我想支持 IE 10 的提示,babel 就帮我编译出能在 IE 10 上正常运行的 JavaScript 代码。

        !!!欢迎 @babel/preset-env。

        我们不妨把 Preset 理解为套餐(预设),每个套餐里打包了不同的插件,

        这样安装套餐就等于一次性安装各类 babel 插件。

        首先在项目下安装:

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

         然后修改 .babelrc:

            {

              "presets": ["@babel/preset-env"]

            }

        运行 npx babel script.js,输出结果。与前面辛苦配置各种插件后的输出结果几 乎一模一样。
        可是,我们还没告诉 babel 我们要支持 IE 10 的,为什么它却 好像预知一切?我们来看 babel-preset-env 
        的一段文档:

          Without any configuration options, babel-preset-env behaves exactly the same as

          babel-preset-latest (or babel-preset-es2015,

                                    babel-preset-es2016,

                                    babel-preset-es2017 together).

            默认情况下,babel-preset-env 等效于三个套餐,而不巧我们前面安装的 几个插件已经囊括在babel-preset-es2015 中。

         那么,如果我只想支持最新版本的 Chrome 呢?

            这时我们可以调整 .babelrc 的配置:

                {

                  "presets": [

                    ["@babel/preset-env", {

                      "targets": {

                        "browsers": ["last 1 Chrome versions"]

                      }

                    }]

                  ]

                }

            最新版本的 Chrome 已经支持箭头函数、class、const,所以 babel 在编 译过程中,不会编译它们。

Ø @babel/polyfill

Babel includes a polyfill that includes a custom regenerator runtime and core-js.

基本上,babel-polyfill 就是 regenerator runtime 加 core-js。

可是,为什么需要 polyfill 这所谓的垫片?前面聊到 @babel/preset-env 时,

不是说只要定义好我想支持的目标浏览器,babel 就能编译出能运行在目标浏览器上的代码吗?
我们暂时从 polyfill 说起。拿 findIndex 来说,IE 11 仍不支持该方法,假如你的代码里写了 findIndex,
IE 11 浏览器会报如下错误:

    Object doesn't support property or method 'findIndex'

    怎么办,这时我们就可以写个 polyfill

        什么是polyfill?

            如果目标环境中已经存在 findIndex,我们什么都不做,如果没有,

            我们就在 Array 的原型中定义一个。这便是 polyfill 的意义。 babel-polyfill 同理。

babel-polyfill 的用法。

 安装 babel-polyfill

     npm install --save @babel/polyfill

 使用 babel-polyfill

     我们需要在程序入口文件的顶部引用 @babel-polyfill:

         require('@babel/polyfill')

         [].findIndex('babel')

         或者使用 ES6 的写法:

         import '@babel/polyfill'

         [].findIndex('babel')
 类似资料: