Appearance
Rspack 源代码导览
项目结构
rspack-course/
├── 04-core-feature/ # 核心功能实现
│ ├── src/
│ │ ├── compiler.rs # Rust 编译器
│ │ ├── parser.rs # Rust 解析器
│ │ └── bridge.js # JavaScript 桥接
│ ├── test/
│ │ ├── compiler.test.js
│ │ ├── parser.test.js
│ │ └── bridge.test.js
│ ├── Cargo.toml
│ ├── package.json
│ └── README.md
├── 05-lesson-plan.md # 课程计划
├── 01-intro.md # 背景研究
├── 02-arch.md # 架构分析
└── 03-code-walkthrough.md # 源代码导览核心文件解析
1. compiler.rs - Rust 编译器
文件路径: src/compiler.rs
核心功能:
- 编译 JavaScript/TypeScript
- 优化代码
- 生成输出
关键代码:
rust
use swc_common::SourceMap;
use swc_ecma_parser::{Parser, StringInput, Syntax};
use swc_ecma_transforms_typescript::strip;
use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
// 编译器
pub struct Compiler {
cm: SourceMap,
}
impl Compiler {
pub fn new() -> Self {
Compiler {
cm: SourceMap::default(),
}
}
// 编译源代码
pub fn compile(&self, source: &str) -> Result<String, Error> {
// 解析
let fm = self.cm.new_source_file(
FileName::Custom("input.js".into()),
source.into()
);
let mut parser = Parser::new(
Syntax::Es(Default::default()),
StringInput::from(&*fm),
None
);
let module = parser.parse_module().map_err(|e| {
Error::ParseError(e.to_string())
})?;
// 转换
let module = strip(Default::default(), module);
// 生成代码
let mut buf = Vec::new();
{
let writer = JsWriter::new(self.cm.clone(), "\n", &mut buf, None);
let mut emitter = Emitter {
cfg: Default::default(),
cm: self.cm.clone(),
comments: None,
writer: writer,
};
emitter.emit_module(&module).map_err(|e| {
Error::EmitError(e.to_string())
})?;
}
Ok(String::from_utf8(buf).unwrap())
}
}设计要点:
- 使用 SWC 解析和转换
- 支持 TypeScript
- 高性能编译
2. parser.rs - Rust 解析器
文件路径: src/parser.rs
核心功能:
- 解析 JavaScript/TypeScript
- 生成 AST
- 提取依赖
关键代码:
rust
use swc_common::SourceMap;
use swc_ecma_parser::{Parser, StringInput, Syntax};
use swc_ecma_visit::{Visit, VisitWith};
// 解析器
pub struct Parser {
cm: SourceMap,
}
impl Parser {
pub fn new() -> Self {
Parser {
cm: SourceMap::default(),
}
}
// 解析源代码
pub fn parse(&self, source: &str) -> Result<Module, Error> {
let fm = self.cm.new_source_file(
FileName::Custom("input.js".into()),
source.into()
);
let mut parser = Parser::new(
Syntax::Es(Default::default()),
StringInput::from(&*fm),
None
);
let module = parser.parse_module().map_err(|e| {
Error::ParseError(e.to_string())
})?;
Ok(module)
}
}
// 依赖提取器
struct DependencyExtractor {
dependencies: Vec<String>,
}
impl Visit for DependencyExtractor {
fn visit_import_decl(&mut self, node: &ImportDecl) {
self.dependencies.push(node.src.value.to_string());
node.visit_children_with(self);
}
fn visit_call_expr(&mut self, node: &CallExpr) {
if let Callee::Expr(expr) = &node.callee {
if let Expr::Ident(ident) = expr.as_ref() {
if ident.sym == "require" {
if let Some(arg) = node.args.first() {
if let Expr::Lit(Lit::Str(s)) = &*arg.expr {
self.dependencies.push(s.value.to_string());
}
}
}
}
}
node.visit_children_with(self);
}
}设计要点:
- 使用 SWC 解析器
- 支持 CommonJS 和 ES6 模块
- 提取依赖关系
3. bridge.js - JavaScript 桥接
文件路径: src/bridge.js
核心功能:
- 连接 Rust 和 JavaScript
- 提供插件 API
- 加载 JavaScript 插件
关键代码:
javascript
import { loadBinding } from '@node-rs/helper'
// 加载 Rust 原生模块
const native = loadBinding(__dirname, 'rspack')
// 编译器桥接
export class Compiler {
constructor(options = {}) {
this.options = options
this.native = new native.Compiler()
}
// 编译源代码
compile(source) {
return this.native.compile(source)
}
}
// 解析器桥接
export class Parser {
constructor(options = {}) {
this.options = options
this.native = new native.Parser()
}
// 解析源代码
parse(source) {
return this.native.parse(source)
}
}
// 插件系统
export class PluginSystem {
constructor(compiler) {
this.compiler = compiler
this.plugins = []
}
// 注册插件
register(plugin) {
if (plugin.apply) {
plugin.apply(this.compiler)
}
this.plugins.push(plugin)
}
}设计要点:
- 使用 NAPI 连接 Rust 和 JavaScript
- 提供与 Webpack 兼容的 API
- 支持插件系统
关键设计决策
1. 使用 SWC
原因:
- SWC 是用 Rust 编写的超快编译器
- 支持 TypeScript 和 JSX
- 与 Webpack 生态兼容
实现:
rust
use swc_ecma_parser::Parser;
use swc_ecma_transforms_typescript::strip;2. 使用 NAPI
原因:
- NAPI 是 Rust 和 Node.js 的标准互操作接口
- 提供高性能的互操作
- 支持异步操作
实现:
rust
#[napi]
pub fn compile_js(source: String) -> Result<String, Error> {
// Rust 编译逻辑
Ok(compiled_code)
}3. 兼容 Webpack API
原因:
- 最小化迁移成本
- 支持现有插件
- 降低学习曲线
实现:
javascript
class Compiler {
constructor(options) {
this.options = options
this.hooks = {
run: new AsyncSeriesHook(['compiler']),
compile: new SyncHook(['params'])
}
}
}测试策略
Rust 测试
rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_compile() {
let compiler = Compiler::new();
let source = "const x = 1;";
let result = compiler.compile(source);
assert!(result.is_ok());
}
}JavaScript 测试
javascript
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { Compiler } from '../src/bridge.js'
describe('Compiler 测试', () => {
it('应该编译 JavaScript', () => {
const compiler = new Compiler()
const source = 'const x = 1'
const result = compiler.compile(source)
assert.ok(result)
})
})性能优化
1. 并行编译
rust
use rayon::prelude::*;
fn compile_modules(modules: Vec<Module>) -> Vec<CompiledModule> {
modules.par_iter()
.map(|module| compile_module(module))
.collect()
}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
}总结
Rspack 的源代码体现了以下设计原则:
- 高性能:利用 Rust 和 SWC 的性能优势
- 生态兼容:通过 JavaScript 桥接兼容 Webpack
- 并发优化:原生支持多线程
- 易于使用:提供与 Webpack 兼容的 API
理解源代码有助于更好地使用和优化 Rspack。
参考资源

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