Rust运行时环境库deno_runtime的使用,高性能JavaScript/TypeScript执行引擎deno_runtime的Rust实现

deno_runtime crate

crates docs

这是Deno CLI的精简版本,移除了TypeScript集成和各种工具(如lint和doc)。基本上只保留了JavaScript执行和Deno的操作系统绑定(ops)。

稳定性

这个crate使用经过实战检验的模块构建,这些模块最初在deno crate中,不过这个crate的API可能会发生快速且破坏性的变化。

MainWorker

这个crate的主要API是MainWorkerMainWorker是一个封装了deno_core::JsRuntime的结构体,带有一组用于实现Deno命名空间的ops。

创建MainWorker时,实现者必须调用MainWorker::bootstrap来准备JS运行时以供使用。

MainWorker高度可配置,允许自定义许多运行时属性:

  • 模块加载实现
  • 错误格式化
  • 支持源映射
  • 支持V8检查器和Chrome Devtools调试器
  • HTTP客户端用户代理、CA证书
  • 随机数生成器种子

Worker Web API

deno_runtime支持Worker Web API。Worker API使用WebWorker结构实现。

创建新的MainWorker实例时,实现者必须提供一个回调函数,该函数在创建新的Worker实例时使用。

所有WebWorker实例都是MainWorker的后代,MainWorker负责设置与子工作线程的通信。每个WebWorker都会生成一个新的OS线程,专门用于该工作线程。

完整示例代码

use deno_runtime::deno_core::error::AnyError;
use deno_runtime::deno_core::FsModuleLoader;
use deno_runtime::permissions::Permissions;
use deno_runtime::worker::MainWorker;
use deno_runtime::worker::WorkerOptions;

#[tokio::main]
async fn main() -> Result<(), AnyError> {
    // 创建一个简单的主工作线程
    let mut worker = MainWorker::bootstrap_from_options(
        "main.js".to_string(),
        // 默认权限
        Permissions::allow_all(),
        WorkerOptions {
            // 使用文件系统模块加载器
            module_loader: Box::new(FsModuleLoader),
            // 其他配置...
            ..Default::default()
        },
    );

    // 执行代码
    worker.execute_main_module("main.js").await?;
    worker.run_event_loop(false).await?;
    
    Ok(())
}

扩展完整示例

以下是一个更完整的示例,展示如何使用deno_runtime创建一个简单的JavaScript运行时环境:

use deno_runtime::deno_core::error::AnyError;
use deno_runtime::deno_core::FsModuleLoader;
use deno_runtime::permissions::Permissions;
use deno_runtime::worker::MainWorker;
use deno_runtime::worker::WorkerOptions;
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<(), AnyError> {
    // 设置要执行的JS文件路径
    let js_path = PathBuf::from("example.js");
    
    // 创建Worker选项
    let options = WorkerOptions {
        module_loader: Box::new(FsModuleLoader),
        startup_snapshot: None,
        extensions: vec![],
        source_map_getter: None,
        format_js_error_fn: None,
        create_web_worker_cb: Arc::new(|_| unimplemented!()),
        maybe_inspector_server: None,
        should_break_on_first_statement: false,
        user_agent: "deno_runtime".to_string(),
        seed: None,
        js_error_create_fn: None,
        get_error_class_fn: None,
        cache_storage_dir: None,
        origin_storage_dir: None,
        blob_store: None,
        broadcast_channel: None,
        shared_array_buffer_store: None,
        compiled_wasm_module_store: None,
        stdio: Default::default(),
        unstable: false,
    };

    // 创建主工作线程
    let mut worker = MainWorker::bootstrap_from_options(
        js_path.to_string_lossy().to_string(),
        Permissions::allow_all(),
        options,
    );

    // 执行主模块
    worker.execute_main_module(&js_path.to_string_lossy()).await?;
    
    // 运行事件循环
    worker.run_event_loop(false).await?;

    Ok(())
}

安装

在项目目录中运行以下Cargo命令:

cargo add deno_runtime

或者在Cargo.toml中添加以下行:

deno_runtime = "0.220.0"

元数据

  • 版本: 0.220.0
  • 8天前更新
  • 2024 edition
  • MIT许可证
  • 119 KiB大小

所有者

  • Ryan Dahl (ry)
  • Bert Belder (piscisaureus)
  • David Sherret (dsherret)
  • Bartek Iwańczuk (bartlomieju)
  • denobot

1 回复

deno_runtime: Rust实现的JavaScript/TypeScript执行引擎

deno_runtime是Deno项目的核心运行时环境库,用Rust实现,提供了高性能的JavaScript/TypeScript执行能力。它是构建在Rust和V8引擎之上的运行时系统,可以嵌入到Rust应用程序中。

主要特性

  • 基于V8引擎的高性能JavaScript/TypeScript执行
  • 支持ES模块系统
  • 内置TypeScript编译器
  • 提供文件系统、网络等基础API
  • 可扩展的安全权限模型
  • 支持Web标准API

安装方法

在Cargo.toml中添加依赖:

[dependencies]
deno_runtime = "0.114.0"  # 请使用最新版本
tokio = { version = "1.0", features = ["full"] }

基本使用方法

1. 创建简单的运行时

use deno_runtime::deno_core::anyhow::Result;
use deno_runtime::deno_core::JsRuntime;
use deno_runtime::deno_core::RuntimeOptions;

async fn run_js(code: &str) -> Result<()> {
    let mut runtime = JsRuntime::new(RuntimeOptions::default());
    runtime.execute_script("[example]", code)?;
    Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
    run_js("console.log('Hello from Deno runtime!');").await
}

2. 执行TypeScript代码

async fn run_ts(code: &str) -&gt; Result<()> {
    let mut runtime = JsRuntime::new(RuntimeOptions {
        will_snapshot: false,
        ..Default::default()
    });
    
    runtime.execute_script("[typescript_example]", code)?;
    Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
    let ts_code = r#"
        interface User {
            name: string;
            age: number;
        }
        
        const user: User = { name: "Alice", age: 30 };
        console.log(user);
    "#;
    
    run_ts(ts_code).await
}

3. 使用扩展和权限系统

use deno_runtime::permissions::Permissions;
use deno_runtime::worker::MainWorker;
use deno_runtime::worker::WorkerOptions;

async fn run_with_permissions() -> Result<()> {
    let options = WorkerOptions {
        extensions: vec![],
        startup_snapshot: None,
        will_snapshot: false,
        ..Default::default()
    };
    
    let permissions = Permissions::allow_all(); // 或自定义权限
    
    let mut worker = MainWorker::bootstrap_from_options(
        "https://example.com/script.js",
        permissions,
        options,
    );
    
    worker.execute_script("[permission_example]", r#"
        try {
            const file = Deno.readTextFileSync("/etc/passwd");
            console.log(file);
        } catch (e) {
            console.error("Permission denied:", e.message);
        }
    "#)?;
    
    worker.run_event_loop(false).await?;
    Ok(())
}

高级用法

1. 自定义扩展

use deno_runtime::deno_core::Extension;
use deno_runtime::deno_core::OpState;
use deno_runtime::deno_core::error::AnyError;

async fn op_custom_hello(
    _state: &mut OpState,
    _args: (),
    _: (),
) -> Result<String, AnyError> {
    Ok("Hello from Rust!".to_string())
}

fn create_extension() -> Extension {
    Extension::builder()
        .ops(vec![
            ("op_custom_hello", deno_runtime::deno_core::op_sync(op_custom_hello)),
        ])
        .build()
}

#[tokio::main]
async fn main() -> Result<(), AnyError> {
    let mut runtime = JsRuntime::new(RuntimeOptions {
        extensions: vec![create_extension()],
        ..Default::default()
    });
    
    runtime.execute_script("[extension_example]", r#"
        const message = Deno.core.ops.op_custom_hello();
        console.log(message);
    "#)?;
    
    Ok(())
}

2. 处理Promise

use deno_runtime::deno_core::futures::FutureExt;

#[tokio::main]
async fn main() -> Result<(), AnyError> {
    let mut runtime = JsRuntime::new(RuntimeOptions::default());
    
    let promise = runtime.execute_script("[promise_example]", r#"
        new Promise((resolve) => {
            setTimeout(() => resolve("Done!"), 1000);
        })
    "#)?;
    
    let result = runtime.resolve_value(promise).await?;
    let result_str = result.to_string(&mut runtime)?;
    println!("Promise resolved with: {}", result_str);
    
    Ok(())
}

性能提示

  1. 重用JsRuntime实例以避免重复初始化开销
  2. 对于频繁执行的脚本,考虑预编译
  3. 合理配置权限以减少安全检查开销
  4. 使用适当的V8标志进行调优

deno_runtime为Rust开发者提供了强大的JavaScript/TypeScript执行能力,适合需要脚本扩展性或构建多语言系统的场景。

回到顶部