vue/cli -- babel


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

1. babel的作用

  1. 语法转换
  2. 通过 Polyfill 方式在目标环境中添加缺失的特性
  3. 源码转换 (codemods)

为什么要用babel转换代码呢:

@babel/polyfill

例:如果我们要使用Array.prototype.find(),但是某个版本的浏览器不支持此方法,我们可以通过babel引入相关的Polyfill文件就可以了

注:Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。

@babel/preset-env

例:

1// 箭头函数
2let Fn = () => {
3    //
4}

因为一些浏览器根本就不识别这些代码,这时候就需要把这些代码转换成浏览器识别的代码。 babel就是做这个事情的。

2. babel的工作原理

Code => AST => new AST => new Code


为了转换我们的代码, babel做了三件事:

  • Parser:解析我们的代码转换为 AST。(@babel/parser)
  • Transformer:利用我们配置好的 plugins/presets把 Parser生成的 AST转变为新的 AST。(@babel/preset-*)
  • Generator:把转换后的 AST生成新的代码(@babel/generator)

从图上看 Transformer占了很大一块比重,这个转换过程就是 babel中最复杂的部分,我们平时配置的 plugins/presets就是在这个模块起作用。

*注:抽象语法树(AST)Abstract Syntax Tree是javascript的最底层结构,babel通过操作AST实现对源代码的修改,可以通过recast插件查看AST的结构

3. babel的使用

  • 正常我们需要安装以下依赖

1npm install --save-dev @babel/core @babel/cli @babel/preset-env
2npm install --save @babel/polyfill

  • 创建一个名为config的配置文件

1module.exports = {
2    presets: [
3        [
4            require('@babel/preset-env'),
5            {
6                targets: {
7                    edge: "17",
8                    firefox: "60",
9                    chrome: "67",
10                    safari: "11.1",
11                },
12                useBuiltIns: 'usage'
13            },
14        ],
15    ],
16    // 上面的浏览器列表只是一个任意示例。您将不得不对其进行调整以适合您要支持的浏览器。
17    plugins: [
18        //
19    ]
20}

  • 运行此命令,将src目录中的所有代码编译为lib

1./node_modules/.bin/babel src --out-dir lib

@babel/cli

Babel带有内置CLI,可用于从命令行编译文件。

@babel/core

@babel/core 包括了整个babel工作流,也就是说在@babel/core里面我们会使用到@babel/parser、transformer[s]、以及@babel/generator。

所有的transformations都会使用babel.config.js文件

@babel/parser

@babel/parser的作用是将源代码解析成 AST ,方便各个插件分析语法进行相应的处理。

@babel/generator

@babel/generator将修正后的AST解码生成js代码。

@babel/preset-env

@babel/preset-env是一个智能预设,可让您使用最新的JavaScript,转化最新语法如箭头函数, class, 扩展运算符,想要转换最新的api还需引入@babel/polyfill

@babel/preset-env接受您指定的任何目标环境,并根据其映射检查它们,以编译插件列表,并将其传递给Babel。

默认情况下,除非设置了target或ignoreBrowserslistConfig选项,@babel/preset-env将使用browserslist配置源

browserslist配置源从以下位置读取:

  1. package.json文件中的browserslist字段
  2. .browserslistrc配置文件
  3. browserslist.config.js 配置文件
  4. 运行环境变量BROWSERSLIST
  5. 默认如下

1"browserslist": [
2    "defaults"
3]
4// defaults => > 0.5%, last 2 versions, Firefox ESR, not dead

useBuiltIns:

  • 此选项配置如何@babel/preset-env处理polyfill
  • 'usage':支持按需引入,优化了core-js导入

@babel/polyfill

babel只负责语法转换,比如将ES6的语法转换成ES5。但如果有些对象、方法,浏览器本身不支持,比如:

  1. 全局对象:Promise、WeakMap 等。
  2. 全局静态函数:Array.from、Object.assign 等。
  3. 实例方法:比如 Array.prototype.includes 等。

此时,需要引入@babel/polyfill来模拟实现这些对象、方法。需要安装在生产依赖中

3. @vue/cli中的babel

我们从package.json入手

1"dependencies": {
2    "axios": "^0.19.1",
3    "core-js": "^3.4.4",
4    "vue": "^2.6.10",
5    "vue-meta": "^2.3.2",
6    "vue-router": "^3.1.3",
7    "vuex": "^3.1.2"
8},
9"devDependencies": {
10    "@vue/cli-plugin-babel": "^4.1.0",
11    "@vue/cli-plugin-eslint": "^4.1.0",
12    "@vue/cli-plugin-unit-jest": "^4.1.0",
13    "@vue/cli-service": "^4.1.0",
14    "@vue/eslint-config-standard": "^4.0.0",
15    "@vue/test-utils": "1.0.0-beta.29",
16    "babel-eslint": "^10.0.3",
17    "babel-plugin-import": "^1.13.0",
18    "eslint": "^5.16.0",
19    "eslint-plugin-vue": "^5.0.0",
20    "image-webpack-loader": "^6.0.0",
21}

core-js

由于自@babel/polyfill7.4.0起已弃用,可以直接添加core-js和设置版本。在@vue/cli项目中,只安装了core-js

core-js是我们能够使用新的API的最重要的包,然而一般情况它隐藏在webpack编译后的代码中,我们一般不会去查看

  • 它是JavaScript标准库的polyfill
    • 最新的 ECMAScript 标准
    • ECMAScript 标准库提案
    • 一些 WHATGW / W3C 标准(跨平台或者 ECMAScript 相关)
  • 它尽可能的进行模块化,让你能选择你需要的功能
  • 它可以不污染全局空间
  • 它和babel高度集成,可以对core-js的引入进行最大程度的优化

@vue/cli-plugin-babel

这就是vue-cli特有的babel插件,其中包括babel7,babel-loader,@vue/babel-preset-app

其中也加载了@babel/core工作流,查看./node_modules/@vue/babel-preset-app,其中配置了:

1presets: [
2    [require('@babel/preset-env'), {
3        useBuiltIns,
4        corejs: 3
5    }]
6]

babel-loader则是webpack配置的预处理器

babel-plugin-import

babel-plugin-import是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式
例:vant

1plugins: [
2    ['import', {
3        libraryName: 'vant',
4        libraryDirectory: 'es',
5        style: true
6    }, 'vant']
7]

babel-eslint

ESLint 默认使用Espree作为其解析器,你可以在配置文件中指定一个不同的解析器

ESLint不支持Babel支持的某些语法节点。使用babel-eslint时,将对ESLint进行修补,并将您的代码转换为ESLint可以理解的代码。相关配置

.eslintrc.js中:

1parserOptions: {
2    parser: 'babel-eslint'
3}



babel 的介绍及其配置的更多相关文章

  1. 03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma

     1 PersonTestMapper.xml中的内容如下: <?xmlversion="1.0"encoding="UTF-8"?> < ...

  2. python学习第二讲,pythonIDE介绍以及配置使用

    目录 python学习第二讲,pythonIDE介绍以及配置使用 一丶集成开发环境IDE简介,以及配置 1.简介 2.PyCharm 介绍 3.pycharm 的安装 二丶IDE 开发Python,以 ...

  3. OSPF协议介绍及配置 (上)

    OSPF协议介绍及配置 (上) 一.OSPF概述 回顾一下距离矢量路由协议的工作原理:运行距离矢量路由协议的路由器周期性的泛洪自己的路由表,通过路由的交互,每台路由器都从相邻的路由器学习到路由,并且加 ...

  4. x-pack 功能介绍及配置传输层安全性(TLS / SSL)

    x-pack 功能介绍及配置传输层安全性(TLS / SSL) 学习了:https://blog.csdn.net/wfs1994/article/details/80411047

  5. mysql多实例介绍及配置

    mysql多实例介绍及配置 1.mysql多实例介绍 1.1 什么是mysql多实例 mysql多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过 ...

  6. 13.LAMP架构介绍及配置

    LAMP架构介绍及配置 LAMP简介与概述 LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用开发环境. LAMP是一 ...

  7. [webpack] webpack-dev-server介绍及配置

    webpack-dev-server是webpack官方提供的一个小型Express服务器.使用它可以为webpack打包生成的资源文件提供web服务.webpack-dev-server官方文档 w ...

  8. Rsync原理介绍及配置应用

    1.前言 基于LAN或WAN的网络应用之间进行数据传输或者同步非常普遍,比如远程数据镜像.备份.复制.同步,数据下载.上传.共享等等.对此,最简单.直接的做法是对数据进行完全复制.然而,数据在网络上来 ...

  9. 日志组件logback的介绍及配置使用方法

    一.logback的介绍 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classic和logback-acc ...

随机推荐

  1. gdk-pixbuf tiff_image_parse函数整数溢出漏洞

    受影响系统:gdk-pixbuf gdk-pixbuf 2.36.6描述:CVE(CAN) ID: CVE-2017-2870 gdk-pixbuf是一个用于以各种格式加载图像和像素缓冲处理的库. 使 ...

  2. Sobel算子 Scharr算子 Laplacian算子

    图像梯度处理 Sobel算子 水平方向: 对于线条A和线条B,右侧像素值与左侧像素值的差值不为零,因此是边界 上下像素值差值为0,左右素值的差值不为零,分布为正负, 离的近的为2,离的远的为1 P5= ...

  3. Numpy库基础___三

    ndarray一个强大的N维数组对象Array •ndarray的操作 索引 a = np.arange(24).reshape((2,3,4)) print(a) #[[[ 0 1 2 3] # [ ...

  4. redis哨兵功能

    redis哨兵功能 redis-Sentinel(哨兵) 前言 当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户都没有实现主从切换的功能 redis ...

  5. ES6中数组新增的方法-超级好用

    Array.find((item,indexArr,arr)=>{}) 掌握 找出第一个符合条件的数组成员. 它的参数是一个回调函数,对所有数组成员依次执行该回调函数. 直到找出第一个返回值为t ...

  6. Java基础 - 异常详解

    异常的层次结构 Throwable Throwable 是 Java 语言中所有错误与异常的超类. Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示 ...

  7. 使用 JWT 来保护你的 SpringBoot 应用

    关键词 写在前面 Spring Boot 创建Spring Boot应用 创建一个Web 应用 使用JWT保护你的Spring Boot应用 添加Spring Security 本文代码 关键词 Sp ...

  8. 多数据源并且数据库类型不同的情况下PageHelper的使用

    一.问题来源 最近开发一个项目需要依赖两个数据源,数据源类型分别为oracle和postgresql,代码中使用com.github.pagehelper分页插件进行分页,代码运行过程中postgre ...

  9. 为什么 char 数组比 Java 中的 String 更适合存储密码?

    另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题.这是一个真正艰难的核心Java面试问题,并且需要对 String 的扎实知识才能回答这个问题. ...

  10. 为什么我们调用 start()方法时会执行 run()方法,为什么 我们不能直接调用 run()方法?

    当你调用 start()方法时你将创建新的线程,并且执行在 run()方法里的代码. 但是如果你直接调用 run()方法,它不会创建新的线程也不会执行调用线程的代码, 只会把 run 方法当作普通方法 ...