SWC介绍
我们来看一下swc
的官方介绍:
SWC (stands for Speedy Web Compiler) is a super-fast TypeScript / JavaScript compiler written in Rust.
swc
的出现其实很大一部分原因是要替换掉工程中的babel
,所以babel
有的功能他几乎都有。
与babel最大的区别可能就是: swc is super-fast
swc官网中还有这样一句话,体现了他的速度:
除了swc
的官方宣传外,Next.js
基于swc
实现了一个Rust
编译器,用来解析编译、打包代码。下面是Next.js
结合swc
之后给出的一个数据:
所以从上面这些数据也可以简单看出来swc
的优势:可以提高开发效率,提升开发体验。
Github
SWC 开源地址
这是一位名叫 kdy1 的韩国97年的小伙子开源的,很牛逼呀!
swc原理分析
(1)新建一个 debug-swc 项目
$ cargo new debug-swc
$ cd debug-swc
目录结构如下:
debug-swc
├── .gitignore
├── Cargo.toml
└── src└── main.rs
(2)添加依赖
Cargo.toml
文件,[dependencies]
配置项下面添加如下内容:
swc_ecma_parser = "0.31.2"
swc_common = "0.7.0"
swc_ecma_ast = "0.26.0"
swc_atoms = "0.2.2"
(3)新增 test.js
文件
根目录下的这个文件,用于 debug swc 的解析之用,内容如下,
const i = 1;
(4)编写 src/main.rs
官方例子 Crate: swc_ecma_parser 几乎不用做任何修改。
为了能展示 swc 解析 JavaScript 代码的结果,我增加了一个 get_identifier_name
函数,用于获取 test.js
代码中的变量名 i
。
extern crate swc_common;
extern crate swc_ecma_parser;use std::path::Path;
use swc_atoms::JsWord;
use swc_common::{errors::{ColorConfig, Handler},sync::Lrc,SourceMap,
};
use swc_ecma_ast::{Decl, Module, ModuleItem, Pat, Stmt};
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax};fn main() {swc_common::GLOBALS.set(&swc_common::Globals::new(), || {let cm: Lrc<SourceMap> = Default::default();let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(cm.clone()));let fm = cm.load_file(Path::new("./test.js")).expect("failed to load test.js");let lexer = Lexer::new(// We want to parse ecmascriptSyntax::Es(Default::default()),// JscTarget defaults to es5Default::default(),StringInput::from(&*fm),None,);let mut parser = Parser::new_from(lexer);for e in parser.take_errors() {e.into_diagnostic(&handler).emit();}let module = parser.parse_module().map_err(|e| {// Unrecoverable fatal error occurrede.into_diagnostic(&handler).emit()}).expect("failed to parser module");if let Ok(identifier_name) = get_identifier_name(&module) {println!("identifier name: {}", identifier_name);}});
}fn get_identifier_name(module: &Module) -> Result<&JsWord, ()> {for module_item in &module.body {if let ModuleItem::Stmt(Stmt::Decl(Decl::Var(var))) = module_item {for decl in &var.decls {if let Pat::Ident(identifier) = &decl.name {return Ok(&identifier.id.sym);}}}}Err(())
}
src/main.rs
的完整源码可以看这里:github: debug-swc/src/main.rs
(4)来看一下执行结果
$ cargo run
执行 cargo run
会先进行 cargo build
,最终结果如下,
我们经过解析 AST 从 test.js 源码中拿到了变量名 i
。
参考文章:
swc–babel的代替者
简单使用SWC
新一代构建工具
SWC体验
编译工具SWC