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, } }