09_webpack_babel

为什么需要babel

对于babel对于前端来说现在是不可缺少的一部分

在开发中,我们想要使用ES6+语法,或者TS,开发Vue项目,他们都是离不开Babel的

 

babel到底是什么呢?

Babel是一个工具链,主要用于处理旧浏览器的兼容如:将es6+转换为向后兼容的javascript,转化TS等

包括:语法转换、源代码转换、Polyfill实现目标缓解缺少的功能等

 

Babel命令行使用

babel本身可以作为一个独立的工具(和postcss一样),不和webpack等构建工具配置来单独使用

安装

npm i @babel/core @babel/cli -D

使用

npx babel src --out-dir dist
  src:是源文件的目录
  dist:指定要输出的文件夹

 无论是使用cli还是babel-loader @babel/core都是必须安装的

Babel的预设

安装:

npm i @babel/preset-env -D

执行
npx babel src --out-dir dist --@babel/preset-env

 

Babel的底层原理

源代码->AST抽象语法树->Byte Code -> V8

源代码->|AST源(ES5+)->AST新(ES5)|->ByteCode->v8
        bable

babel是如何做到将我们的一段代码(ES6、TS)转换成另外一段代码(ES5)的呢?

  从一种源代码(原生语言)转换成另外一种源代码(目标代码),这是什么的工作呢?

  就是编译器,实际上我们可以将babel看成就是一个编译器

  Babel编译器的作用就是将我们的源代码,转换成浏览器可以直接识别的另外一段源代码

babel也拥有编译器的工作流程:

  解析阶段(parsing)

  转换阶段(Transformation)

  生成阶段(Code Generation)

 

源代码->词法分析(LexicalAnalysis)->tokens数组->语法分析(syntactic analysis)Parsing->AST抽象语法树->遍历->访问->应用插件->新的AST->目标代码

那么他们怎么知道需要适配哪些浏览器?它是使用Browserslist根据你配置的.browserslistrc文件查询对应的浏览器,再根据preset应用对应的插件

但是你也可以自定义需要适配哪些浏览器

      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', {
                //适配的目标浏览器
                targets: ['chrome 88']
              }]
            ]
          }
        }
      }

具体可以配置哪些参数可以去官网查询@babel/preset-env · Babel (babeljs.io)

 

 

在通常旧的项目中我们还会发现有一些这样的配置

{
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['es2015','stage-3']
            ]
          }
        }
      }

@babel/preset-env把es2015和stage-3做了一个中和,所以我们现在只需要写@babel/preset-env就可以了

es2015:把es5+转化为es2015

 

Stage-X的preset

要了解State-X,需要先了解TC39的组织

  TC39是指技术委员会(Technical Committee)第39号
  它是ECMA的一部分,ECMA是"ECMAScript"规范下的JavaScript
  ECMAScript规范定义了JavaScript如何一步一步的进化、发展

TC39遵循的原则是:分阶段加入不同的语言特性,新流程涉及四个不同的Stage

  Stage 0:strawman(稻草人),任何尚未提交作为正式提案的讨论、想法变更或者补充都被认为是第0阶段的,稻草人

  Stage 1:proposal(提议),提案已经被正式化,并期望解决此问题,还需要观察与其他提案的相互影响

  Stage 2:draft(草稿),Stage2的提案应提供规范初稿,草稿。此时,语言的实现者开始观察runtime的具体实现是否合理

  Stage 3:candidate(候补),Stage3提案是建议的候选提案。在这个高级阶段,规范的编辑人员和审评人员必须在最终规范上签字。Stage3的提案不会有太大的改变,在对外发布之前只是修正一些问题

  Stage 4:finished(完成),进入Stage4的提案将包括在ECMAScript的下一个修订版本中

 

Babel的Stage-X设置

在babel7之前(如babel6中),我们会经常看到这种设置方式

  他表达的含义是使用对应的babel-preset-stage-x预设
  但是babel7开始,已经不建议使用了,建议使用preset-env来设置

 

babel的配置文件

像之前的postcss一样我们可以将babel的配置信息放到一个独立的文件中,babel给我们提供了两种配置文件的编写

  bable.config.json(或者.js .cjs .mjs)文件;
  .babelrc.json(或者.babelrc,.js,.cjs,.mjs)文件

他们两个有什么区别呢?目前很多的项目都采用了多包管理的方式(babel本身、element-plus、umi等)

  .babelrc.json:早期使用较多的配置方式,但是对于配置Monrepos项目是比较麻烦的;
  babel.config.json(babel7):可以直接作用域Monorepos项目的子包,更加推荐

以前开发一个项目,一个项目中有很多的子包

1.以前是把这些子包都放在一个项目中
2.把子包放在多个项目中
3.monorepos:一个项目中有很多的子包,一个子包开发一个单独的项目,每个子包都可以有单独的package.json,如果在多个项目中都使用到了babel,那么就可以共享一个babel.config.json

 

新建一个babel.config.js

module.exports = {
  presets: [
    "@babel/preset-env"
  ]
}

 

如果你发现当前的代码并没有转成ES5的代码:如箭头函数没有转之类的,你可能没有配置.browserslistrc文件

或者你也可以在output中加入environment的配置项

output: {
    environment: {
      arrowFunction: false,
    }
}

  

posted @ 2022-04-16 19:21  Mr-Hou88888  阅读(32)  评论(0编辑  收藏  举报