大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
Babel 可以将最新的 JavaScript 代码(例如 ES6)转换为旧版本浏览器支持的 JavaScript,它甚至可以转换 TypeScript。
Babel 根据开发者定义的配置读取源代码,并编译更新的 JavaScript 功能,例如:箭头函数等。 Babel的代码转换主要包括三个核心流程:
整体转换流程如下图所示:
SWC 是一个可扩展的基于 Rust 的平台,用于下一代快速开发工具。 Next.js、Parcel 和 Deno 等工具以及 Vercel、字节跳动、腾讯、Shopify 等公司都在使用 SWC。
在 Github 上,SWC 已经有超过 26.3k 的 star 和 1k 的 fork,每周的平均下载量达到了 1983k。目前有超过 6.2k 的项目使用 SWC、项目贡献人数也达到了 200+,增长势头非常迅猛。
SWC 可用于编译和打包工作,是一个超快速的 JavaScript 编译器。 对于编译,SWC 读取 JavaScript / TypeScript 文件,并输出所有主流浏览器都支持的代码。在性能上,SWC 比其他打包方案具有明显的优势。
SWC 也是 JavaScript 的转译器,它是用 Rust 编写的,比 Babel 快得多。 Rust 以其性能优势、可靠性而著称,Rust鼓励企业使用它重写部分、甚至全部代码。
例如以下非常成功的迁移Rust的示例:
Rust 如此高效的原因之一是它处理垃圾收集的方式,这是一种内存管理方法,即及时释放不再需要的内存资源。 由于 Rust 在编译时决定哪些内存资源不再需要,因此带来性能改进。
众所周知,代码转译是一个昂贵的过程,这就是为什么用 Rust 编写的转译器性能更高的原因。
可以将SWC看做一个包,可以从 NPM 包管理器安装。 首先,在目录的根目录中运行命令:
// 使用 `cd` 转到正确的目录,然后运行
mkdir swc_project
//实例化package.json
npm init
// 安装swc core和cli
npm install --save-dev @swc/core @swc/cli
通过运行以上代码就可以安装 SWC core和 CLI。 核心包将帮助进行构建设置,而 CLI 包可以在终端中使用命令运行。本文专注于使用 CLI 工具来转换 JavaScript 文件。 假设在目录的根目录中有以下 JavaScript 文件:
// 文件名:async.js
const fetch = require("node-fetch");
async function getData() {
let res = await fetch("https://feadvance.dev.com/todos/1");
let json = await res.json();
console.log('data', json);
}
getData();
// 调用函数
可以运行以下命令进行转译:
// 运行此命令会将转换后的数据发送到标准输出
// 并将在终端中打印出来
npx swc async.js
// 运行这个将创建一个名为 `output.js` 的新文件
// 其中包含转换后的数据
npx swc async.js -o output.js
// 运行此命令将创建一个名为 transpiledDir 的新目录
// 并将转译原始目录中的所有文件
npx swc src -d transpiledDir
现在如果希望将 SWC 作为一个工具包含在构建系统中。此时,需要使用 Webpack 作为更高级和可配置的构建器。下面是一个简单的package.json配置文件内容:
{
"name": "swc-project-demo",
"version": "1.0.0",
"scripts": {
"build": "rm -rf ./dist && webpack",
"start": "webpack-dev-server"
},
"license": "MIT",
"devDependencies": {
//开发依赖
"@swc/core": "^1.1.39",
"css-loader": "^3.4.0",
"html-loader": "^0.5.5",
"swc-loader": "^0.1.9",
// ...其他配置项
},
"dependencies": {
// 依赖项
...
}
}
下面是用于构建和启动应用程序的配置,存储在 webpack.config.js 文件中,Webpack 会自动获取该文件。
但此配置中最重要的部分是 swc-loader,它允许转换带有 .js 或 .jsx 文件扩展名的 JavaScript 文件:
// 下面是webpack配置
module.exports = {
mode: "development",
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js'
},
// 是告诉 Webpack 从何处提供内容以及定义一个端口来侦听请求
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
},
module: {
rules: [
{
test: /.jsx?$/ ,
exclude: /(node_modules|bower_components)/,
use: {
// `.swcrc` in the root can be used to configure swc
loader: "swc-loader"
}
},
{
// 不同loader配置
test: /.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /.scss/i,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
},
plugins: [
//定义这个插件以简化包含 Webpack 包的 HTML 文件服务过程
new HTMLWebpackPlugin({
filename: "./index.html",
template: path.join(__dirname, 'public/index.html')
})
]
};
通过在 Webpack 配置中设置 swc-loader,已经完成了转译 JavaScript 文件的一半。 但是,仍然需要指示 SWC 如何转换文件。SWC 通过在根目录中定义一个名为 .swcrc 的配置来进行能力扩展。
在配置中可以使用正则表达式,以仅匹配具有 .ts 文件扩展名的文件。 此外,通过 jsx.parser 配置,指示 SWC 使用哪个解析器进行转译(可以是 typescript / ecmascript)。
// .swcrc
{
"test": ".*.ts#34;,
"jsc": {
"parser": {
"syntax": "typescript",
// 转移文件语法
"tsx": false,
"decorators": true,
"dynamicImport": true
}
}
}
现在,假设想在上面的 webpack SWC 示例中使用 React,可以使用一个名为 .jsx 的特定文件扩展名来编写 React 组件:
// App.jsx 组件
// 全局 dependencies
import React from 'react';
import ReactDOM from 'react-dom';
// APP组件
const App = () => {
return 我的 SWC 应用程序
;
};
ReactDOM.render(, document.querySelector("#root"));
通过 Webpack 提供此文件需要已经拥有并在上面定义的正确的 webpack 加载程序。 它还需要 .swcrc 文件中的正确转译设置。 现在通过这种方法,可以使用现代 JavaScript (ES2019) 的最新功能,并在转译时支持 .jsx 文件。 此外,如果 React 项目需要额外的转译设置,可以自有配置:
// .swcrc 自行配置扩展
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": true
// 支持JSX
}
}
}
首先,以一种人工方式进行比较,即以同步方式运行 Babel 和 SWC 的代码转换。 众所周知,JavaScript 是单线程的,在实际应用程序中不可能以异步方式运行大量计算。 但这仍然会给出一个速度指标。 下面的基准测试是在单核 CPU 上运行(由 SWC 项目的维护者执行的测试):
尽管 SWC 的 ES3 转换过程成本更高,但与 Babel 相比,SWC 的转译速度提升明显。
下面想对更现实的场景进行基准测试,即针对 await Promise.all() 运行示例,这是处理 JavaScript 操作的更昂贵、真实的场景。 在这个基准测试中,CPU 内核的数量和并行计算开始发挥作用。 在运行的另一个基准测试中,进行了两个实验。 两者都使用了具有 8 个 CPU 内核且并行度为 4 的机器。
第一个实验运行了 4 个Promise:
第二个实验运行了 100 个Promise:
可以从这些数字中发现: Babel 在异步操作中的性能正在下降,因为 Babel 在事件循环上工作。 这与 SWC 形成对比,SWC 在工作线程上运行并且可以很好地随着 CPU 内核的数量进行扩展。
总的来说,看到这SWC、Babel两种工具之间存在明显的速度差距, SWC 在单线程上比 Babel 快 20 倍左右,而在多核异步操作过程中快 60 倍左右。
本文主要和大家介绍下SWC,即一个使用Rust编写的Babal替代品。文章从什么是Babel、什么是SWC、SWC使用、SWC与Babel性能对比等几个角度展开。相信通过本文的比较,大家对选择SWC还是Babel都已经比较清楚了。因为篇幅有限,如果有兴趣,文末的参考资料提供了大量优秀文档以供学习。
https://blog.logrocket.com/why-you-should-use-swc/
https://dev.to/this-is-learning/what-is-babel-and-swc-49cp
https://blog.csdn.net/feiyanaffection/article/details/125599084
https://blog.csdn.net/csdnnews/article/details/121241393
更新时间:2024-08-04
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号