SWC介绍

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官网中还有这样一句话,体现了他的速度:

img

除了swc的官方宣传外,Next.js基于swc实现了一个Rust编译器,用来解析编译、打包代码。下面是Next.js结合swc之后给出的一个数据:

img

所以从上面这些数据也可以简单看出来swc的优势:可以提高开发效率,提升开发体验

Github

SWC 开源地址
这是一位名叫 kdy1 的韩国97年的小伙子开源的,很牛逼呀!
在这里插入图片描述

swc原理分析

(1)新建一个 debug-swc 项目

$ cargo new debug-swc
$ cd debug-swc

目录结构如下:

扫描二维码关注公众号,回复: 14686256 查看本文章
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 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


参考文章:
swc–babel的代替者
简单使用SWC
新一代构建工具
SWC体验
编译工具SWC

猜你喜欢

转载自blog.csdn.net/feiyanaffection/article/details/125600809