大家好,欢迎来到IT知识分享网。
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原理分析
(1)新建一个 debug-swc 项目
$ cargo new debug-swc $ cd debug-swc
目录结构如下:
debug-swc ├── .gitignore ├── Cargo.toml └── src └── main.rs
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 ecmascript Syntax::Es(Default::default()), // JscTarget defaults to es5 Default::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 occurred e.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
。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/132046.html