深入浅出 Babel:现代 JavaScript 的编译器

wallhaven-288vd9.jpeg

在现代前端开发中,JavaScript 的版本更新速度非常快,新的语法和特性层出不穷。然而,旧版本的浏览器并不总是支持这些新特性。为了确保代码的兼容性和稳定性,我们需要一个工具来将现代 JavaScript 代码转换为旧版本的代码。Babel 就是这样一个工具。

什么是 Babel?

Babel 是一个 JavaScript 编译器,主要用于将现代 JavaScript 代码(ES6+)转换为向后兼容的 JavaScript 代码,以便在旧版本的浏览器或环境中运行。Babel 还支持转换 JSX 语法(用于 React)和 TypeScript。

// Babel 接收到的输入是: ES2015 箭头函数
[1, 2, 3].map(n => n + 1);// Babel 输出: ES5 语法实现的同等功能
[1, 2, 3].map(function(n) {return n + 1;
});

为什么需要 Babel?

  1. 向后兼容性:现代 JavaScript 特性(如箭头函数、类、模块等)在旧版本的浏览器中不被支持。Babel 可以将这些新特性转换为旧版本的 JavaScript,使代码在所有浏览器中都能运行。
  2. 代码优化:Babel 插件可以帮助优化代码,例如移除未使用的代码、压缩代码等。
  3. 扩展性:Babel 的插件系统非常强大,可以根据需要添加各种功能,如转换 JSX、TypeScript 等。

如何使用 Babel?

1. 安装与配置

安装 Node.js 和 npm

首先,你需要安装 Node.js 和 npm。你可以从 Node.js 官方网站下载并安装最新版本的 Node.js,它会自动安装 npm。

安装 Babel

在你的项目目录中,使用 npm 安装 Babel 的核心包和 CLI 工具:

npm install --save-dev @babel/core @babel/cli @babel/preset-env
配置 Babel

在项目根目录下创建一个 .babelrc 文件,并添加以下内容:

{"presets": ["@babel/preset-env"]
}

这个配置文件告诉 Babel 使用 @babel/preset-env 预设来转换现代 JavaScript 代码。

2. 基本使用

编写现代 JavaScript 代码

src 目录下创建一个 index.js 文件,并编写一些现代 JavaScript 代码:

// src/index.js
const greet = (name) => {console.log(`Hello, ${name}!`);
};class Person {constructor(name) {this.name = name;}greet() {greet(this.name);}
}const john = new Person('John');
john.greet();
使用 Babel 编译代码

在终端中运行以下命令,将 src 目录下的代码编译到 dist 目录:

npx babel src --out-dir dist

编译后的代码将被输出到 dist 目录中。你可以查看 dist/index.js 文件,看到 Babel 将现代 JavaScript 代码转换为向后兼容的代码。

3. 插件与预设

Babel 的强大之处在于其插件和预设系统。你可以根据需要添加各种插件和预设。

安装 JSX 和 TypeScript 支持

如果你使用 React 和 TypeScript,可以安装相关的预设:

npm install --save-dev @babel/preset-react @babel/preset-typescript
更新 .babelrc 文件

更新 .babelrc 文件以支持 JSX 和 TypeScript:

{"presets": ["@babel/preset-env","@babel/preset-react","@babel/preset-typescript"]
}
编写 JSX 和 TypeScript 代码

src 目录下创建一个 App.tsx 文件,并编写一些 JSX 和 TypeScript 代码:

// src/App.tsx
import React from 'react';interface Props {name: string;
}const App: React.FC<Props> = ({ name }) => {return <h1>Hello, {name}!</h1>;
};export default App;
编译代码

再次运行 Babel 编译命令:

npx babel src --out-dir dist --extensions ".js,.jsx,.ts,.tsx"

4. 与 Webpack 集成

在实际项目中,Babel 通常与 Webpack 一起使用,以便更好地管理和打包代码。

安装 Webpack 和相关插件
npm install --save-dev webpack webpack-cli babel-loader
创建 Webpack 配置文件

在项目根目录下创建一个 webpack.config.js 文件,并添加以下内容:

const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')},module: {rules: [{test: /\.(js|jsx|ts|tsx)$/,exclude: /node_modules/,use: {loader: 'babel-loader'}}]},resolve: {extensions: ['.js', '.jsx', '.ts', '.tsx']}
};
更新 npm 脚本

package.json 文件中添加一个构建脚本:

"scripts": {"build": "webpack"
}
运行构建

在终端中运行以下命令:

npm run build

Webpack 将使用 Babel 编译代码,并将输出打包到 dist/bundle.js 文件中。

5. 实践项目

为了更好地理解 Babel,建议创建一个小型项目,使用 Babel 编译代码,并尝试在项目中使用不同的 Babel 插件和预设。

项目结构
my-babel-project/
├── dist/
├── node_modules/
├── src/
│   ├── App.tsx
│   └── index.js
├── .babelrc
├── package.json
└── webpack.config.js
完整代码示例
  • src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';ReactDOM.render(<App name="John" />, document.getElementById('root'));
    
  • src/App.tsx

    import React from 'react';interface Props {name: string;
    }const App: React.FC<Props> = ({ name }) => {return <h1>Hello, {name}!</h1>;
    };export default App;
    
  • .babelrc

    {"presets": ["@babel/preset-env","@babel/preset-react","@babel/preset-typescript"]
    }
    
  • webpack.config.js

    const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')},module: {rules: [{test: /\.(js|jsx|ts|tsx)$/,exclude: /node_modules/,use: {loader: 'babel-loader'}}]},resolve: {extensions: ['.js', '.jsx', '.ts', '.tsx']}
    };
    
  • package.json

    {"name": "my-babel-project","version": "1.0.0","scripts": {"build": "webpack"},"devDependencies": {"@babel/core": "^7.15.0","@babel/cli": "^7.15.0","@babel/preset-env": "^7.15.0","@babel/preset-react": "^7.14.5","@babel/preset-typescript": "^7.15.0","babel-loader": "^8.2.2","webpack": "^5.51.1","webpack-cli": "^4.8.0"},"dependencies": {"react": "^17.0.2","react-dom": "^17.0.2"}
    }
    

🌲 Babel 的工作原理

Babel 使用 AST 把不兼容的代码编译成 es5 版本,因为大多数浏览器都支持这个版本的 JavaScript 代码。

Babel 的工作流程

Babel 是一个强大的 JavaScript 编译器,它的工作流程可以分为以下几个主要步骤:

  1. 解析(Parsing):将 ES6+ 代码转换为抽象语法树(AST)。
  2. 转换(Transforming):使用插件对 AST 进行遍历和修改。
  3. 生成(Generating):将修改后的 AST 转换回 ES5 代码。

image.png

1. 解析(Parsing)

首先,Babel 使用 @babel/parser(以前称为 Babylon)将 ES6+ 代码解析成抽象语法树(AST)。AST 是代码的结构化表示,便于后续的分析和转换。

import { parse } from '@babel/parser';const code = `const greet = (name) => { console.log(\`Hello, \${name}!\`); };`;
const ast = parse(code, { sourceType: 'module' });console.log(ast);
2. 转换(Transforming)

接下来,Babel 使用 @babel/traverse 对 AST 进行遍历,并通过插件对 AST 进行修改。插件可以添加、删除或修改 AST 节点,从而实现代码的转换。

import traverse from '@babel/traverse';traverse(ast, {enter(path) {if (path.isIdentifier({ name: 'greet' })) {path.node.name = 'sayHello';}}
});console.log(ast);

在这个例子中,我们使用 @babel/traverse 遍历 AST,并将所有名为 greet 的标识符(Identifier)修改为 sayHello

3. 生成(Generating)

最后,Babel 使用 @babel/generator 将修改后的 AST 转换回 ES5 代码。

import generate from '@babel/generator';const output = generate(ast, {}, code);
console.log(output.code);

在这个例子中,@babel/generator 将修改后的 AST 转换回代码,并输出最终的 ES5 代码。

完整示例

下面是一个完整的示例,展示了 Babel 的整个工作流程:

import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
import generate from '@babel/generator';// 输入的 ES6+ 代码
const code = `const greet = (name) => { console.log(\`Hello, \${name}!\`); };`;// 1. 解析:将代码转换为 AST
const ast = parse(code, { sourceType: 'module' });// 2. 转换:使用插件对 AST 进行遍历和修改
traverse(ast, {enter(path) {if (path.isIdentifier({ name: 'greet' })) {path.node.name = 'sayHello';}}
});// 3. 生成:将修改后的 AST 转换回 ES5 代码
const output = generate(ast, {}, code);console.log(output.code);
// 输出:const sayHello = (name) => { console.log(`Hello, ${name}!`); };

Babel 的性能优化

Babel 的性能优化是一个重要的主题,特别是在大型项目中,编译速度可能成为瓶颈。以下是一些常见的 Babel 性能优化技巧和策略,帮助你提高编译速度和效率。

1. 使用缓存

1.1 babel-loader 的缓存功能

在使用 Webpack 时,可以启用 babel-loader 的缓存功能,以减少重复编译的时间。

// webpack.config.js
module.exports = {// ...module: {rules: [{test: /\.(js|jsx|ts|tsx)$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {cacheDirectory: true // 启用缓存}}}]}
};
1.2 Babel 缓存插件

Babel 还提供了一个缓存插件 babel-plugin-transform-runtime,可以减少重复的辅助代码。

npm install --save-dev @babel/plugin-transform-runtime

在 Babel 配置文件中启用插件:

{"plugins": ["@babel/plugin-transform-runtime"]
}

2. 并行编译

2.1 使用 thread-loader

在 Webpack 中,可以使用 thread-loader 来启用多线程编译,从而提高编译速度。

npm install --save-dev thread-loader

在 Webpack 配置文件中添加 thread-loader

// webpack.config.js
module.exports = {// ...module: {rules: [{test: /\.(js|jsx|ts|tsx)$/,exclude: /node_modules/,use: ['thread-loader', // 启用多线程编译'babel-loader']}]}
};
2.2 使用 parallel-webpack

parallel-webpack 是一个用于并行化 Webpack 构建的工具,可以显著提高构建速度。

npm install --save-dev parallel-webpack

使用 parallel-webpack 运行 Webpack:

npx parallel-webpack --config webpack.config.js

3. 按需加载

按需加载可以减少初始加载时间和编译时间。使用 @babel/plugin-syntax-dynamic-import 插件可以实现按需加载。

npm install --save-dev @babel/plugin-syntax-dynamic-import

在 Babel 配置文件中启用插件:

{"plugins": ["@babel/plugin-syntax-dynamic-import"]
}

在代码中使用动态导入:

import(/* webpackChunkName: "my-chunk-name" */ './myModule').then(module => {// 使用模块
});

4. 减少 Babel 处理的文件数量

通过合理配置 excludeinclude 选项,可以减少 Babel 处理的文件数量,从而提高编译速度。

// webpack.config.js
module.exports = {// ...module: {rules: [{test: /\.(js|jsx|ts|tsx)$/,exclude: /node_modules/, // 排除 node_modules 目录include: /src/, // 仅处理 src 目录use: 'babel-loader'}]}
};

5. 使用更少的 Babel 插件和预设

每个 Babel 插件和预设都会增加编译时间。尽量只使用必要的插件和预设,可以显著提高编译速度。

示例:精简 Babel 配置
{"presets": [["@babel/preset-env", {"targets": {"browsers": ["last 2 versions", "ie >= 11"]}}]],"plugins": ["@babel/plugin-transform-arrow-functions","@babel/plugin-transform-classes"]
}

6. 使用 Babel 的 env 选项

Babel 的 env 选项允许你根据不同的环境(如开发、生产)配置不同的插件和预设,从而优化编译速度。

示例:使用 env 选项
{"env": {"development": {"presets": ["@babel/preset-env"],"plugins": ["@babel/plugin-transform-runtime"]},"production": {"presets": ["@babel/preset-env"],"plugins": ["@babel/plugin-transform-runtime", "@babel/plugin-transform-react-                    inline-elements"]}}
}

7. 使用 Babel 的 ignore 选项

Babel 的 ignore 选项允许你忽略特定的文件或目录,从而减少编译时间。

示例:使用 ignore 选项
{"ignore": ["node_modules", "dist"]
}

8. 使用 babel-preset-envuseBuiltIns 选项

babel-preset-envuseBuiltIns 选项可以按需引入 polyfill,从而减少编译后的代码体积。

示例:使用 useBuiltIns 选项
{"presets": [["@babel/preset-env", {"useBuiltIns": "usage","corejs": 3}]]
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信息打点web篇----企业宏观资产打点

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 专栏描述&#xff1a;因为第一遍过信息收集的时候&#xff0c;没怎么把收集做回事 导致后来在实战中&#xff0c;遭遇资产获取少&#xff0c;可渗透点少的痛苦&#xff0c;如今决定 从头来过&#xff0c;全面全方位…

python安装系列问题

python3.4版本以上安装了python之后自带安装python。 1、换源 以Windows&#xff0c;清华源为例&#xff1a; 直接在user目录中创建一个pip目录&#xff0c;例如&#xff1a;C:\Users\xx\pip&#xff0c;新建文件pip.ini&#xff0c;内容如下: [global] index-url https:/…

C#的Switch语句3(如何为一段代码应用多个case标签)

文章目录 上一篇文章中断函数执行堆叠caseswitch中实用的字符串函数将字符串转换为小写 switch例子 上一篇文章 C#的Switch语句2 中断函数执行 switch语句内部可以使用return语句&#xff0c;这为控制程序流程和函数返回值提供了一种直接的方式。 当在switch语句块中遇到re…

CleanShot X for Mac v4.7 屏幕截图录像工具(保姆级教程,小白轻松上手,简单易学)

Mac分享吧 文章目录 一、准备工作二、部分特有功能效果1、截图软件的普遍常用功能&#xff08;画框、箭头、加文字等&#xff09;都具备&#xff0c;不再详细介绍2、ABCD、1234等信息标注&#xff08;每按一下鼠标&#xff0c;即各是A、B、C、D...等&#xff09;3、截图更换背…

SD-WAN组网如何帮助企业降低网络成本?

企业在构建IT网络时&#xff0c;常常面临节省费用和提升效益的挑战。IT开销主要包括设备、网络和维护成本。利用OgCloud的SD-WAN组网方案&#xff0c;企业可以有效地应对这些问题。 企业专线网络的高成本问题 企业专线的费用较高&#xff0c;而且数据不能同时在多条专线上传输。…

【linux】Valgrind工具集详解(十六):交叉编译、移植到arm(失败)

1、源码下载 官网:https://valgrind.org/ 源码:https://valgrind.org/downloads/current.html 2、配置 ./configure CC=arm-linux-gnueabihf-gcc \CXX=arm-linux-gnueabihf-g++ \AR=arm-linux-gnueabihf-ar \--host=arm-linux-gnueabihf \--pr

Postman如何在本地测试服务接口

项目架构及背景&#xff1a; 网关微服务多个业务微服务 服务部署在阿里云上&#xff0c;文件服务器用的是OSS。配置参数用Nacos进行统一管理。通过构建docker镜像包部署各业务微服务以及网关服务。 需求&#xff1a; 某一个业务微服务中开发了若干接口&#xff0c;需要在本地…

如何使用Indicator-Intelligence收集与威胁情报相关的域名和IPv4地址

关于Indicator-Intelligence Indicator-Intelligence是一款针对威胁情报的强大数据收集工具&#xff0c;该工具可以帮助广大研究人员通过威胁情报活动中生成的静态文件来查找与威胁行为相关的域名和IPv4地址。 需要注意的是&#xff0c;请在目标组织授权后再使用该工具进行安…

IFM易福门SV7500SV4200涡街流量计型号都是进口的。

IFM易福门SV7500SV4200涡街流量计型号都是进口的。工程余料。

数据质量管理-规范性管理

数据质量管理简介 数据质量管理是一个持续性的管理动作&#xff0c;有些人在做数据质量管理的时候会陷入一步到位的误区&#xff0c;想要通过一个工具、平台&#xff0c;或者一套质检规则就完成整体的数据质量管理&#xff0c;而实际数据质量管理从数据接入的那一刻就需要介入…

热门常用在线免费工具

图片&绘图 免费且易于使用的在线PDF工具 nullhttps://tools.pdf24.org/zh/免费的在线图片压缩工具 TinyPNG – Compress WebP, PNG and JPEG images intelligentlyFree online image compressor for faster websites! Reduce the file size of your WEBP, JPEG, and PNG…

互联网应用主流框架整合之SpingMVC运转逻辑及高级应用

Spring MVC处理器的执行过程 在SpringMVC的流程中&#xff0c;它会把控制器的方法封装为处理器(Handler)&#xff0c;为了更加灵活&#xff0c;SpringMVC还提供了处理器的拦截器&#xff0c;从而形成了一条包括处理器和拦截器的执行链&#xff0c;即HandlerExecutionChain&…

第21篇 Intel FPGA Monitor Program的使用<四>

Q&#xff1a;如何编译运行创建好的Intel FPGA Monitor Program工程呢&#xff1f; A&#xff1a;上一篇的Nios II汇编语言简易应用程序创建完成后&#xff0c;点击Intel FPGA Monitor Program的Action-->Compile即编译程序&#xff0c;在Info&Errors区域显示编译结果…

[Vulnhub] BrainPan BOF缓冲区溢出+Man权限提升

信息收集 Server IP AddressPorts Open192.168.8.105TCP: $ nmap -p- 192.168.8.105 -sC -sV -Pn --min-rate 1000 Starting Nmap 7.92 ( https://nmap.org ) at 2024-06-10 04:20 EDT Nmap scan report for 192.168.8.105 (192.168.8.105) Host is up (0.0045s latency). N…

XTDrone-多机仿真-配置教程

启动python脚本生成多机launch文件 cd ~/XTDrone/coordination/launch_generator python3 generator.py将生成出来的launch文件复制到PX4固件的launch文件夹 cp ~/XTDrone/coordination/launch_generator/multi_vehicle.launch ~/PX4_Firmware/launch/启动多机PX4仿真 cd ~/…

MyBatis框架基础

文章目录 1 MyBatis概述2 MyBatis入门2.1 相关依赖2.2 properties配置文件2.3 预编译SQL 3 基本操作3.1 新增操作3.2 删除操作3.3 更新操作3.4 查询操作 4 动态SQL4.1 XML映射文件4.2 if/set/where标签4.3 foreach标签4.4 sql/include标签 5 参考资料 1 MyBatis概述 MyBatis是…

每日复盘-202406019

今日关注&#xff1a; 20240619 六日涨幅最大: ------1--------300868--------- 杰美特 五日涨幅最大: ------1--------300462--------- 华铭智能 四日涨幅最大: ------1--------300462--------- 华铭智能 三日涨幅最大: ------1--------300462--------- 华铭智能 二日涨幅最大…

IntelliJ IDEA软件下载安装手册:从官方下载到配置启动全流程详解(Windows版)

一、访问官方下载页面 首先&#xff0c;您需要通过官方渠道访问IntelliJ IDEA的下载页面。在您的浏览器中输入官方网址&#xff1a; https://www.jetbrains.com/idea/download/&#xff0c;进入官方下载页面。 二、选择合适的版本下载 在官方下载页面&#xff0c;您将看到多…

Linux虚拟机安装nginx并进行浏览器访问 - 附带常见问题和常用指令(实施必备)

1、Linux安装Nginx 1.1、下载Nginx安装包 Linux Nginx-1.25.5 官方其他版本 1.2、解压安装包 tar -zxvf nginx-1.25.5.tar.gz 1.3、安装依赖包 由于我使用的是1.25.5版本&#xff0c;所以需要加入依赖包 # yum install pcre pcre-devel # yum install zlib-devel 1.4、配置…

[linux] 系统的基本使用

用户系统&#xff1a; 之前提到&#xff0c;linux是个多用户系统&#xff0c;所以要使用linux&#xff0c;首先你得是个用户 用户&#xff1a;普通用户管理员 每一个用户有自己的用户名密码&#xff0c; 会话(session):一个终端使用服务器的全过程 从你用户登录&#xff0c;到你…