babel使用及其底层原理介绍

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

日常使用

作用

  1. 语法转化,将es6+语法转化为es5
  2. Polyfill支持是指通过代码模拟实现旧版浏览器或环境中缺失的现代JavaScript API的技术手段
  3. 将jsx语法转化为js

使用

复制代码
npm i @babel/cli@^7.27.2 @babel/core@^7.27.1

1.在src新建index.js

复制代码
const add = (a, b) => {
  return a + b;
};

2.添加箭头函数转化插件

复制代码
npm i @babel/plugin-transform-arrow-functions@^7.27.1

3.packjson.js

复制代码
 "scripts": {
    "build": "babel src -d dist"
  },

4.babel.config.js

复制代码
module.exports = {
  plugins:['@babel/plugin-transform-arrow-functions']
};

5.执行命令npm run build

则可以在dist下面得到

babel提供了大量的插件,但是这样每个语法转化都要下载对应的插件很麻烦,所以babel提供了@babel/preset-env,这个预设集成了很多插件只需要安装这个就可以了,下面是关于babel预设的介绍

  1. vue-cli创建的项目可以直接使用@vue/cli-plugin-babel
bash 复制代码
npm i @vue/cli-plugin-babel@~4.5.0
javascript 复制代码
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

2.基础通用版

复制代码
npm install --save-dev @babel/preset-env
javascript 复制代码
module.exports = {
  presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
  plugins: ['@vue/babel-plugin-jsx'],
};

解释:

  1. presets 配置项

    预设(presets)是一组预定义的插件集合,用于处理特定场景的转译需求。

    • @babel/preset-env 是一个智能预设,能根据目标环境(浏览器或 Node.js)自动确定需要转译的语法特性。
    • { targets: { node: 'current' } } 表示转译后的代码要兼容当前运行的 Node.js 版本,不需要额外兼容更旧的 Node 版本。
  2. plugins 配置项

    插件(plugins)用于处理特定的语法扩展或转译需求。

    • @vue/babel-plugin-jsx 是 Vue 官方提供的 Babel 插件,用于支持在 Vue 项目中使用 JSX 语法(类似 React 的 JSX 写法),让开发者可以用更灵活的方式编写 Vue 组件。

@vue/cli-plugin-babel/preset和@babel/preset-env区别

特性 @vue/cli-plugin-babel/preset @babel/preset-env
本质 Vue CLI 专用预设(基于 @babel/preset-env 扩展) 基础通用预设(无框架依赖)
适用项目 Vue CLI 创建的 Vue 项目 所有 JS 项目(无框架限制)
包含内容 内置 @babel/preset-env + Vue 专属配置 仅核心 JS 语法转译逻辑
配置复杂度 低(自动集成 Vue CLI 配置) 高(需手动配置 targets 等参数)

babel.config.json和babel.config.js区别

当你的 Babel 配置简单、固定且无动态逻辑 时,适合用 babel.config.json

javascript 复制代码
// babel.config.json
{
  "presets": ["@babel/preset-env"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

当你的配置需要动态逻辑或复杂处理 时,必须用 babel.config.js(因为 JSON 不支持代码逻辑)

javascript 复制代码
// babel.config.js
module.exports = (api) => {
  // 判断当前环境(开发/生产)
  const isProduction = api.env('production');
  
  return {
    presets: [
      [
        '@babel/preset-env',
        {
          // 生产环境兼容更多旧浏览器,开发环境只兼容最新浏览器
          targets: isProduction ? '>0.25%, not dead' : 'last 1 chrome version'
        }
      ]
    ]
  };
};

解释

  • isProductionfalse(开发环境)时,targets 设为 'last 1 chrome version'

    • 表示只需要兼容「最新版本的 Chrome 浏览器」。
    • 开发环境不需要兼容太多旧浏览器,这样可以减少转译工作量,加快开发时的编译速度。

深入理解

babel底层原理

babel是核心通过解析 - 遍历转换 - 生成三个步骤实现的,通过parser解析成ast抽象语法树,然后通过traverse遍历转化,最后通过generator生成将ast转化回代码

bash 复制代码
npm i  @babel/generator@^7.28.3 @babel/parser@^7.28.3 @babel/traverse@^7.28.3 

packjson.json

bash 复制代码
 "scripts": {
    "build": "node index.js"
  },

src/index.js

javascript 复制代码
const a=1
const b=2

index.js

javascript 复制代码
import parser from "@babel/parser";
import traverse from "@babel/traverse";
import generator from "@babel/generator";

import fs from "node:fs";

if (!fs.existsSync("./dist")) {
  fs.mkdirSync("./dist");
}
const codePath = "./src/index.js";
const destPath = "./dist/index.js";

const code = fs.readFileSync(codePath, {
  encoding: "utf-8",
});

// babel底层 先语法解析 生成ast(抽象语法树),然后遍历ast,按照一定规则查找需要转化的节点 最后生成解析代码

// 1. 语法解析
const ast = parser.parse(code);
// console.log("ast", ast);

// 2.游历ast
//  访问者模式
const visitor = {
  VariableDeclaration(path) {
    if (path.node.kind === "const" || path.node.kind === "let") {
      path.node.kind = "var";
    }
  },
};

traverse.default(ast, visitor);

// // 3. 生成代码
const result = generator.default(ast, {}, code);
console.log("result", result.code);

fs.writeFileSync(destPath, result.code);
相关推荐
若梦plus21 天前
Babel中微内核&插件化思想的应用
前端·babel
前端工作日常1 个月前
我学习到的babel插件移除Flow 类型注解效果
前端·babel·前端工程化
前端工作日常1 个月前
我学习到的 Babel 配置
前端·babel·前端工程化
hans7748829681 个月前
通过为前端项目接入GeoGebra,初步研究AI时代数学教案的生成方案
前端·vite·babel
_一两风1 个月前
深入浅出Babel:现代JavaScript开发的"翻译官"
前端·babel
bigyoung1 个月前
babel 自定义plugin中,如何判断一个ast中是否是jsx文件
前端·javascript·babel
Nu112 个月前
@babel/preset-env的corejs、@babel/plugin-transform-runtime的corejs之间区别
前端·babel
MiyueFE2 个月前
深入浅出Babel插件开发:从AST到代码转换的完整指南
前端·babel
Canvas4 个月前
如何用Babel获取JS函数的使用情况?
react.js·babel