比较NEAR BOS的两个框架：ROC与Além

前言

BOS 的全称是 Blockchain Operation System，是由 NEAR 开发的一个框架，旨在为用户开发开放网络应用程序提供支持。擅长 React 的开发者可以在 NEAR Sandbox 直接编写 React 代码来构建应用程序。发布后的 React 代码将托管到 IPFS，实现了去中心化前端。

在智能合约方面，为了提高前端开发者的操作体验，NEAR 通过内置对象 NEAR，提供了便捷的智能合约调用方式，开发者只需使用 NEAR.call 和 NEAR.view 函数即可轻松调用智能合约。

由于 BOS 相当于一个单页应用程序，构建小型应用特别方便。但对于构建稍微大型的应用程序，诞生了两个框架：ROC 和 Além。

本文主要介绍 BOS 的这两个框架之间的对比。

介绍

1. BWE

BWE 全称是 BOS Web Engine，是 NEAR 官方开发的一个引擎。官方介绍如下。

BOS Web Engine (BWE) 是下一代去中心化前端执行环境。BWE 使去中心化前端开发更加接近标准 React 开发，并提供增强的、浏览器支持的安全性。Note: “BOS Web Engine” 是一个暂定名称，将在发布前更改

2. Além

Além 是由推特用户 wpdas 开发。据推文介绍，该产品通过在 NEAR 的 BOS 上显着加快页面加载速度来优化用户体验。 Além 是一个 web3 JavaScript/TypeScript 库，允许您在 NEAR 协议的区块链操作系统上创建 Web3 应用程序。所有组件和其他资源都转换为 Near VM 可以理解的文件，允许您以与 React 类似的方式创建应用程序。您可以利用 JSX 的全部功能，因为 Além 管理有状态组件和无状态组件的子组件，确保它们得到正确处理和理解。

IDE 和预览对比

1. BWE

BWE 可以使用在线编辑器 Sandbox 进行编辑。可以进行实时预览。适合短期做活动，和快速开发原型并发布的产品。

2. Além

Além 可以通过脚手架进行本地开发，如 Installation 页面展示，该软件可以通过 alem 脚手架进行创建一个项目。本地 vscode 编辑，和 react 一样方便。

预览方面，在开发中通过本地链接可以实时预览。http://127.0.0.1:8080/alem-lib.testnet/widget/Index 。同样，如果要通过本地 bos 进行实时预览，可以在 https://test.near.org/flags 这个网址，将 flags 设置为 http://127.0.0.1:8080/api/loader，即可在 https://test.near.org/alem-lib.testnet/widget/Index 这边预览发布后的地址。

react hooks 兼容性

1. BWE

通过以下代码测试

Copy
import {useState, useEffect, useRef, useCallback, useMemo} from 'react';

function MyComponent() {
const [msg, setMsg] = useState("");
const ref = useRef(null);
useEffect(( ) => {
setMsg("Message");
console.log({ref: ref.current})
}, []);
const res = useMemo(() => {
return 123;
}, []);
console.log({res})
return (

{msg}
<button onClick={
useCallback(()=> {
console.log("123")
}, [])
}>Click Me

);
}

export default MyComponent as BWEComponent;

useState ✅

useEffect ✅

useRef ✅

useCallback ✅

useMemo ✅

2. Alem

Alem 使用同样的代码进行测试，结果为 useRef 不存在这个函数。

Copy
import { useState, useEffect, useCallback, useMemo } from 'react';

const App = () => {
const [msg, setMsg] = useState("");
useEffect(() => {
setMsg("Message");
console.log({ ref: ref.current })
}, []);
const res = useMemo(() => {
return 123;
}, []);
console.log({ res })
return (

{msg}
<button onClick={
useCallback(() => {
console.log("123")
}, [])
}>Click Me

);
};

export default App;

useState ✅

useEffect ✅

useRef ❌

useCallback ✅

useMemo ✅

packages 和兼容性

我列举了下 web3 前端常见会需要的一些库。进行对比他们的是否可以正常使用。

1. BWE

使用如下代码进行测试

Copy
import Big from 'big.js';
import dayjs from 'dayjs';
import clsx from 'classnames';
import lodash from 'lodash';
import s from './styles.module.css';
import toast, { Toaster } from 'react-hot-toast';

const notify = () => toast('Here is your toast.');

function HelloWorld() {
return (

Num: {Big(10).pow(8).minus(1).toFixed()}
Date: {dayjs('1713161771413').format('YYYY MMMM DD')}
AAA
<button className={clsx(
s.Red,
s.Small
)}>
Click Me

{lodash.uniq([2, 1, 2, 3, 3, 3]).join(", ")}
Make me a toast
<Toaster />

);
}

export default HelloWorld as BWEComponent;

渲染后的效果：

big.js ✅

classnames ✅

dayjs ✅

lodash ✅

react-hot-toast ❌

优点：

无须定义 esm 地址

可以通过 import 导入包

支持 typescript

缺点：

在测试 classnames 的时候，发现 css modules 似乎无法正常运行。

button click 在渲染的时候也无法运行。

2. Alem

首先定义 esm 导包，新建一个文件，名字叫 alem.modules.json

Copy
{
"javascript-time-ago": "https://unpkg.com/javascript-time-ago@2.5.9/bundle/javascript-time-ago.js",
"dayjs": "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/dayjs.min.js",
"classnames": "https://cdnjs.cloudflare.com/ajax/libs/classnames/2.5.2/index.min.js",
"big.js": "https://cdnjs.cloudflare.com/ajax/libs/big.js/6.2.1/big.min.js",
"lodash": "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"
}

新建一个 HomePage.jsx

Copy
import { useModule, useState } from "alem";

const HomePage = () => {
const [date, setDate] = useState("");
const [cn, setCn] = useState("");
const [big, setBig] = useState("");
const [lo, setLo] = useState("");
useEffect(() => {
useModule({
code: `dayjs('1713161771413').format('YYYY MMMM DD')`,
onComplete: (data) => {
setDate(data)
},
});
useModule({
code: `classNames("Red", "Small")`,
onComplete: (data) => {
setCn(data)
},
});
useModule({
code: `Big(10).pow(8).minus(1).toFixed()`,
onComplete: (data) => {
setBig(data)
},
});
useModule({
code: `_.uniq([2, 1, 2, 3, 3, 3]).join(", ")`,
onComplete: (data) => {
setLo(data)
},
});
}, []);
return
Date: {date}
Small Red
Big: {big}
Lodash: {lo}

};

export default HomePage;

修改index.jsx

Copy
import HomePage from "./components/HomePage";
import { ModulesProvider } from "alem";

const App = () => {
return (

dayjs testing:
<ModulesProvider />
<HomePage />

);
};

export default App;

预览效果：

big.js ✅

classnames ✅

dayjs ✅

lodash ✅

react-hot-toast ❌

优点：

可以自定义 esm 的路径，选择版本

css 运行良好

button click 运行良好

缺点：

不支持 typescript

useModule 使用不简单，只能调用一些简单的 js 文件并运算成结果