Skip to content

Rspack 架构分析

整体架构

Rspack 采用 Rust 和 JavaScript 混合架构,利用 Rust 的高性能和 JavaScript 的生态兼容性。

┌─────────────────────────────────────────────────────┐
│                   Rspack Compiler                  │
├─────────────────────────────────────────────────────┤
│  1. Rust Core (高性能核心)                        │
│     - Parser (解析器)                              │
│     - Compiler (编译器)                             │
│     - Optimizer (优化器)                            │
├─────────────────────────────────────────────────────┤
│  2. JavaScript Bridge (JS 桥接)                 │
│     - NAPI (Node API)                              │
│     - Plugin System (插件系统)                       │
│     - Loader System (加载器系统)                      │
├─────────────────────────────────────────────────────┤
│  3. Runtime (运行时)                              │
│     - Module Runtime (模块运行时)                     │
│     - HMR Runtime (热更新运行时)                     │
└─────────────────────────────────────────────────────┘

核心组件

1. Rust Core

Rust 核心负责高性能的编译任务。

职责: 解析 JavaScript/TypeScript,编译和优化代码,生成最终输出。

关键模块:parser:使用 SWC 解析代码,compiler:编译模块和生成代码,optimizer:优化生成的代码。

优势:性能:Rust 的零成本抽象,安全:内存安全和线程安全,并发:原生支持多线程。

2. JavaScript Bridge

JavaScript 桥接负责与 Webpack 生态的兼容。

职责: 加载 JavaScript 插件,执行 JavaScript Loader,提供插件 API。

关键技术:NAPI:Rust 和 Node.js 互操作,serde:序列化和反序列化,napi-rs:Rust NAPI 绑定。

实现:

rust
use napi_derive::napi;

#[napi]
pub fn compile_js(source: String) -> Result<String, Error> {
    // Rust 编译逻辑
    Ok(compiled_code)
}

3. Plugin System

插件系统提供与 Webpack 兼容的扩展接口。

钩子类型:SyncHook:同步钩子,AsyncSeriesHook:异步串行钩子,AsyncParallelHook:异步并行钩子。

插件注册:

javascript
class MyPlugin {
  apply(compiler) {
    compiler.hooks.compile.tap('MyPlugin', (params) => {
      // 编译前处理
    })
  }
}

4. Loader System

加载器系统支持 Webpack 的 Loader。

执行流程:

Source → Loader 1 → Loader 2 → ... → Loader N → Output

Loader 执行:

javascript
function babelLoader(source) {
  return babel.transform(source, {
    presets: ['@babel/preset-env']
  }).code
}

数据流

编译流程

Entry File

┌──────────────┐
│  Parser      │ (Rust - SWC)
│  解析 AST     │
└──────────────┘

┌──────────────┐
│  Compiler    │ (Rust)
│  编译模块     │
└──────────────┘

┌──────────────┐
│  Optimizer   │ (Rust)
│  优化代码     │
└──────────────┘

Output Files

HMR 流程

File Change

┌──────────────┐
│  Watcher     │ (Rust)
│  监听变化     │
└──────────────┘

┌──────────────┐
│  Incremental  │ (Rust)
│  增量编译     │
└──────────────┘

┌──────────────┐
│  HMR Runtime │ (JS)
│  热更新       │
└──────────────┘

Browser Update

性能优化

1. 并行编译

Rspack 利用 Rust 的并发特性实现并行编译:

rust
use rayon::prelude::*;

fn compile_modules(modules: Vec<Module>) -> Vec<CompiledModule> {
    modules.par_iter()  // 并行迭代
        .map(|module| compile_module(module))
        .collect()
}

优势: 充分利用多核 CPU,大幅提升编译速度,自动负载均衡。

2. 增量编译

只重新编译变化的模块:

rust
fn incremental_compile(
    old_graph: &ModuleGraph,
    changed_files: Vec<PathBuf>
) -> ModuleGraph {
    let mut new_graph = old_graph.clone();
    
    for file in changed_files {
        let module = compile_module(file);
        new_graph.update_module(module);
    }
    
    new_graph
}

优势: 减少重复编译,提升增量构建速度,降低 CPU 使用率。

3. 持久化缓存

缓存编译结果到磁盘:

rust
fn load_from_cache(key: &str) -> Option<CompiledModule> {
    // 从磁盘加载缓存
}

fn save_to_cache(key: &str, module: &CompiledModule) {
    // 保存到磁盘缓存
}

优势: 跨构建保持缓存,减少编译时间,提升开发体验。

内存管理

Rust 内存安全

Rust 的所有权系统确保内存安全:

rust
struct Module {
    id: String,           // 拥有 String
    source: String,        // 拥有 String
    dependencies: Vec<String>,  // 拥有 Vec
}

优势: 无内存泄漏,无数据竞争,零成本抽象。

JavaScript 互操作

通过 NAPI 安全地与 JavaScript 交互:

rust
#[napi]
pub fn create_module(id: String, source: String) -> Module {
    Module {
        id,
        source,
        dependencies: Vec::new(),
    }
}

优势: 类型安全,自动内存管理,高效的数据传递。

错误处理

Rust 错误处理

使用 Result 类型处理错误:

rust
fn compile_module(source: &str) -> Result<CompiledModule, CompileError> {
    match parse(source) {
        Ok(ast) => Ok(generate_code(ast)),
        Err(e) => Err(CompileError::ParseError(e)),
    }
}

优势: 显式错误处理,类型安全,便于调试。

JavaScript 错误传递

将 Rust 错误传递到 JavaScript:

rust
#[napi]
pub fn compile_js(source: String) -> Result<String, Error> {
    compile_module(&source)
        .map_err(|e| Error::from(e))
}

总结

Rspack 的架构体现了四个核心特点:高性能利用 Rust 的性能优势,实现比 Webpack 快数倍的构建速度;生态兼容通过 JavaScript 桥接机制兼容 Webpack 的 loader 和 plugin,降低迁移成本;并发优化原生支持多线程,充分利用多核 CPU;内存安全利用 Rust 的所有权系统,避免内存泄漏和安全问题。理解 Rspack 的架构有助于更好地使用和优化 Rspack。

参考资源

Rspack 架构文档Rust 官方文档NAPI 文档

架构师AI杜公众号二维码

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态