Xray插件开发入门:使用xray_js创建第一个WASM扩展

Xray插件开发入门:使用xray_js创建第一个WASM扩展

【免费下载链接】xray An experimental next-generation Electron-based text editor 【免费下载链接】xray 项目地址: https://gitcode.com/gh_mirrors/xray/xray

你还在为Xray编辑器功能扩展发愁吗?本文将带你从零开始,使用xray_js开发第一个WebAssembly(WASM)插件,无需复杂的C++知识,只需基础的JavaScript和Rust语法,30分钟即可完成一个能实际运行的插件。读完本文后,你将掌握WASM扩展的创建流程、Rust代码编写、JavaScript桥接以及插件测试的完整步骤。

插件开发准备工作

在开始之前,请确保你的开发环境已安装以下工具:

  • Node.js(v14+)和Yarn包管理器
  • Rust编译器(通过rustup安装)
  • wasm-pack工具(用于将Rust编译为WASM)

Xray项目中提供了完整的插件开发基础设施,核心模块包括:

  • xray_js: 提供Rust到JavaScript的桥接能力
  • xray_wasm: WASM模块编译配置
  • memo_js: 协作编辑核心功能支持
# 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/xray/xray
cd xray/xray

# 安装依赖
cd xray_js && yarn install

理解Xray插件架构

Xray采用分层架构设计,WASM插件运行在独立的沙箱环境中,通过预定义的接口与主程序通信。这种设计确保了插件的安全性和稳定性,同时提供接近原生的性能。

Xray架构图

核心通信流程如下:

  1. 主程序通过JsSink发送消息到WASM插件
  2. 插件通过Receiver接收消息并处理
  3. 处理结果通过Sender返回给主程序
  4. 所有通信采用JSON格式序列化

详细的协议规范可参考客户端-服务器协议文档

创建WASM插件项目

Xray提供了现成的插件开发模板,我们可以基于xray_js模块快速创建新项目:

# 创建插件项目目录
mkdir -p xray_plugins/hello-wasm
cd xray_plugins/hello-wasm

# 初始化Rust项目
cargo init --lib

# 创建package.json
yarn init -y

修改Cargo.toml文件,添加必要的依赖:

[package]
name = "hello_wasm"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
wasm-bindgen = "0.2.83"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
xray_core = { path = "../../xray_core" }

编写Rust核心代码

创建src/lib.rs文件,这是我们插件的核心逻辑部分。以下是一个简单的"Hello World"示例,实现文本转换功能:

use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};

#[wasm_bindgen]
#[derive(Serialize, Deserialize)]
pub struct TextTransformRequest {
    input: String,
    operation: String,
}

#[wasm_bindgen]
#[derive(Serialize, Deserialize)]
pub struct TextTransformResponse {
    output: String,
    success: bool,
}

#[wasm_bindgen]
pub fn transform_text(request_json: &str) -> String {
    let request: TextTransformRequest = serde_json::from_str(request_json).unwrap();
    
    let output = match request.operation.as_str() {
        "uppercase" => request.input.to_uppercase(),
        "lowercase" => request.input.to_lowercase(),
        "reverse" => request.input.chars().rev().collect(),
        _ => format!("Unsupported operation: {}", request.operation),
    };
    
    let response = TextTransformResponse {
        output,
        success: true,
    };
    
    serde_json::to_string(&response).unwrap()
}

这段代码定义了一个文本转换函数,支持三种操作:大写转换、小写转换和字符串反转。通过JSON格式与JavaScript进行数据交换。

编译Rust代码为WASM

使用wasm-pack工具将Rust代码编译为WASM模块:

# 在xray_js目录下执行编译
wasm-pack build --target web --out-dir pkg

编译成功后,会在pkg目录下生成以下文件:

  • hello_wasm_bg.wasm: 编译后的WASM二进制文件
  • hello_wasm.js: JavaScript包装器
  • hello_wasm.d.ts: TypeScript类型定义

Xray的构建系统已内置WASM编译支持,相关配置可查看xray_js/webpack.config.js

创建JavaScript桥接层

接下来需要创建JavaScript桥接代码,将WASM模块集成到Xray插件系统中。在xray_js/src目录下创建hello_wasm.ts

import { transform_text } from '../pkg/hello_wasm';
import { WorkTree } from './index';

// 注册插件
export function registerHelloWasmPlugin(workTree: WorkTree) {
    // 添加自定义命令
    workTree.registerCommand('hello-wasm:uppercase', async (path: string) => {
        const content = await workTree.readFile(path);
        const request = {
            input: content,
            operation: 'uppercase'
        };
        const response = JSON.parse(transform_text(JSON.stringify(request)));
        if (response.success) {
            await workTree.writeFile(path, response.output);
            return { success: true, message: 'Text converted to uppercase' };
        }
        return { success: false, message: response.output };
    });

    // 注册右键菜单
    workTree.registerContextMenuItem({
        label: 'Hello WASM',
        submenu: [
            {
                label: 'Convert to Uppercase',
                command: 'hello-wasm:uppercase'
            },
            {
                label: 'Convert to Lowercase',
                command: 'hello-wasm:lowercase'
            },
            {
                label: 'Reverse Text',
                command: 'hello-wasm:reverse'
            }
        ]
    });
}

这段代码实现了:

  1. 导入WASM模块的transform_text函数
  2. 注册自定义命令
  3. 添加右键菜单选项

完整的API文档可参考memo_js README

测试插件功能

Xray提供了完善的测试框架,在xray_js/test目录下创建hello_wasm.test.ts

import { WorkTree } from '../src/index';
import { registerHelloWasmPlugin } from '../src/hello_wasm';

describe('Hello WASM Plugin', () => {
    let workTree: WorkTree;
    
    beforeEach(async () => {
        // 初始化测试环境
        workTree = await WorkTree.create(
            'test-replica',
            'base-commit',
            [],
            {
                baseEntries: async () => [],
                baseText: async () => 'test content'
            }
        );
        registerHelloWasmPlugin(workTree);
    });
    
    test('uppercase command', async () => {
        // 创建测试文件
        await workTree.createFile('test.txt', 'text');
        await workTree.writeFile('test.txt', 'hello world');
        
        // 执行命令
        const result = await workTree.executeCommand('hello-wasm:uppercase', 'test.txt');
        
        // 验证结果
        expect(result.success).toBe(true);
        const content = await workTree.readFile('test.txt');
        expect(content).toBe('HELLO WORLD');
    });
});

运行测试:

# 在xray_js目录下执行
yarn test

测试框架配置可参考xray_js/test/tsconfig.json

插件打包与分发

插件开发完成后,需要打包为Xray支持的格式。创建plugin.json配置文件:

{
    "name": "hello-wasm",
    "version": "0.1.0",
    "main": "dist/hello_wasm.js",
    "author": "Your Name",
    "description": "A simple WASM plugin for Xray",
    "engines": {
        "xray": ">=0.1.0"
    }
}

使用webpack打包插件:

yarn build

打包后的插件位于dist目录,可通过Xray的插件管理器安装。

总结与进阶方向

通过本文,你已掌握使用xray_js开发WASM插件的基础流程:

  1. 搭建开发环境
  2. 编写Rust核心逻辑
  3. 编译为WASM模块
  4. 创建JavaScript桥接层
  5. 测试与打包

进阶学习方向:

Xray的插件系统还支持更多高级功能,如自定义UI组件、快捷键绑定、文件系统操作等。查看Xray插件开发指南获取更多信息。

现在,你已经具备开发Xray WASM插件的基本能力,快去扩展你喜爱的编辑器功能吧!

【免费下载链接】xray An experimental next-generation Electron-based text editor 【免费下载链接】xray 项目地址: https://gitcode.com/gh_mirrors/xray/xray

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值