Babel基础知识

发布时间 2023-10-10 11:32:12作者: songxia777

Babel中文官网

Babel 入门教程-阮一峰

Babel博客教程-姜瑞涛

Bilibili--系列Babel视频学习教学

1. 介绍

1.1 简介

Babel 是一个 JavaScript 编译器。

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

Babel是一个工具集,主要用于将ES6版本的JavaScript代码转为ES5等向后兼容的JS代码,从而可以运行在低版本浏览器或其它环境中

比如:我们在代码中使用了ES6箭头函数

// 编译前
var fn = (num) => num + 2;

但如果是运行在一些低版本的浏览器里面,就会报错;经过Babel编译之后的代码就可以运行在IE11以及更低版本的浏览器中了

// 编译后
var fn = function fn(num) {
  return num + 2;
}

Babel就是做了这样的编译转换工作,来让我们不用考虑浏览器的兼容性问题,只要专心于代码的编写工作

1.2 历史

babel5及之前是一个包含CLI工具+编译器+转换器的集合工具包;babel6之后进行了拆分,集合包被分成多个包

  • babel-cli,Babel命令行转码工具,如果我们使用命令行进行Babel转码就需要安装它
  • babel-core,包括了Node有关的API和require钩子
  • babel-polyfill,可以建立一个完整的ES2015环境

babel6默认情况下不携带任何转换器,需要自行安装所需的插件和转换器,通过babel-xxx来安装对应的工具包。

而Babel7用了npm的private scope,把所有的包都挂载@babel下,通过@babel/xxx来安装,不用在node_modules下看到一堆的babel-xxx包

1.3 @Babel/coreBabel/cli

1.3.1 @Babel/core

@babel/core我们在很多地方都看到,它是Babel进行转码的核心依赖包,我们常用的babel-cli和babel-node都依赖于它。

Babel的运行方式总共可以分为三个阶段:解析(parsing)、转换(transforming)和生成(generating);负责解析阶段的插件是@babel/parser,其作用就是将源码解析成AST;而负责生成阶段的插件是@babel/generator,其作用就是将转好好的AST重新生成代码。

而@babel/core本身不具备转换处理的功能,它把转换的功能拆分到一个个插件(plugins)中;因此当我们不添加任何插件的时候,输入输出代码是相同的

1.3.2 @babel/cli

@babel/cli是Babel自带了一个内置的CLI命令行工具,我们就可以通过命令行来编译文件;它有两种调用方式,可以通过全局安装或者本地安装调用,选用一种即可,推荐在项目本地安装

// 全局安装调用
npm install --g @babel/cli
babel index.js -o output.js

// 本地安装调用
npm install --save-dev @babel/cli
npx babel index.js -o output.js

可以使用以下命令参
image

1.3.3 babel-cli基本用法

# 转码结果输出到标准输出
$ babel example.js

# 转码结果写入一个文件
# --out-file 或 -o 参数指定输出文件
$ babel example.js --out-file compiled.js
# 或者
$ babel example.js -o compiled.js

# 整个目录转码
# --out-dir 或 -d 参数指定输出目录
$ babel src --out-dir lib
# 或者
$ babel src -d lib

# -s 参数生成source map文件
$ babel src -d lib -s

1.4 配置文件

虽然可以在命令行中配置各种插件(plugins)或者预设,但是这样就不利于管理和维护,因此Babel推荐通过配置文件的方式来进行管理。

Babel的配置文件主要有.babelrc.babelrc.jsbabel.config.jspackage.json,他们的配置选项都是相同的,作用也是一样,主要区别在于格式语法的不同,因此我们在项目中只需要选择其中一种即可

1.4.1 .babelrc配置:

可以在配置文件中加入一些插件或者预设,来扩展@babel/core的转换功能;只需要将对应的插件或预设名字加入数组即可

比如我们常用的ES6箭头函数,就是通过@babel/plugin-transform-arrow-functions这个插件来转换

{
  "presets": [...],
  "plugins": ["@babel/plugin-transform-arrow-functions"]
}

如果需要对插件和预设设置参数,即是如下的格式

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

spec属性

这个属性主要是给其他插件传递参数(比如@babel/plugin-transform-arrow-functions),默认是false,设为true后,箭头函数会有以下改变:

  1. 将箭头函数生成的函数用.bind(this)包裹一下,以便在函数内部继续使用this,而不是重命名this。
  2. 加一个检查防止函数被实例化
  3. 给箭头函数加一个名字

1.4.2 .babelrc.jsbabel.config.js的配置

同样都是JS语法,通过module.exports的方式输出配置

module.exports = function (api) {
  api.cache(true);
  const presets = [ ... ];
  const plugins = [ ... ];
  if (process.env["ENV"] === "prod") {
    plugins.push(...);
  }
  return {
    presets,
    plugins
  };
}

1.4.3 package.json 配置

增加babel的属性即可

{
  "name": "demo",
  "version": "1.0.0",
  "babel": {
    "presets": [ ... ],
    "plugins": [ ... ],
  }
}

1.4.4 babel.config.json 配置(Babel7推荐)

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "ie": "10", // 最低兼容ie10浏览器
          "edge": "11",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "usage" // 按需加载
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-transform-arrow-functions",
    "@babel/plugin-transform-block-scoping",
    "@babel/plugin-transform-object-assign"
  ]
}

targets属性

targets主要是用来描述我们在项目中想要支持的目标浏览器环境,它可以是Browserslist格式的查询

{
  "targets": "> 0.25%, not dead"
}

或者可以是一个对象,用来描述支持的最低版本的浏览器:

{
  "targets": {
    "chrome": "58",
    "ie": "11"
  }
}

其他的浏览器版本还可以是:operaedgefirefoxsafariiosandroidnodeelectron

1.5 Babel插件和预设

Babel的插件大致可以分为语法插件转换插件

  • 语法插件:作用于解析阶段,使得babel能够解析更多的语法,官方的语法插件以babel-plugin-syntax开头
  • 转换插件:在转换这一步把源码转换并输出,官方的转换插件以babel-plugin-transform(正式)或 babel-plugin-proposal(提案)开头

2. 使用

2.1 方式一:引入第三方js(一般不推荐使用)

<!--1  引入browser.min.js文件 -->
<!--注意:browser.min.js  IE9以下本身就不支持-->
 <script type="text/javascript" src="browser.min.js"></script>

<!--2.  设置script类型: type="text/babel" -->
<script type="text/babel">
  let a = [1, 2, 3];
  console.log(a);

  const show = name => console.log(name);
  show('你好呀');
</script>

2.2 方法二:Babel命令编译

2.2.1 初始化项目

自动生成一个 package.json

npm init -y

2.2.2 安装babel项目依赖

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

以下项目包是根据根据需要安装使用

可以兼容更低版本的浏览器,比如IE等更低
npm install --save @babel/polyfill 

单独安装箭头函数转换的插件(可以安装、也可以不安装,如果不安装,就可以使用babel的预设项)
npm install --save-dev @babel/plugin-transform-arrow-functions

2.2.3 babel配置文件

新建一个 babel配置文件:babel.config.json,主要是进行babel预设的配置

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "ie":"10", //这个是自己添加的,最好是加上
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "usage"  // 按需加载
      }
    ]
  ]
  "plugins": [
    "@babel/plugin-transform-member-expression-literals",
    "@babel/plugin-transform-property-literals"
  ]
}

2.2.4 创建npm命令

在package.json中创建快捷执行命令

  "scripts": {
      "dev": "babel src --out-dir src --minified --ignore 'src/*.min.js,src/**/*.min.js,src/**/**/*.min.js' --out-file-extension .min.js"
        
        // 这个是执行箭头函数转换的命令
        "build-arrow": "babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions"
    },

--minified:压缩混淆

--ignore:忽略某些文件

--out-file-extension .min.js :设置文件扩展名

更多配置参考:https://www.babeljs.cn/docs/babel-cli#安装

2.2.5 命令执行

npm run build

在phpstrom中的配置

$FilePathRelativeToProjectRoot$ --out-dir $FileDirRelativeToProjectRoot$ --minified --presets @babel/env --ignore "template/wap/skin/**/*.min.js,template/wap/skin/**/**/*.min.js" --out-file-extension .min.js"