# Blocklet 服务器 Web 界面

> 用于管理 Blocklet 服务器的 Web 仪表盘

## Blocklet 服务器开发

### 启动 Blocklet 服务器开发环境

1. 在当前（core/webapp）目录下创建 `.env.development` 文件。
2. 将以下内容复制到 `.env.development` 文件中，将 `ABT_NODE_BASE_URL` 改为你的本地局域网 IP。

```ini
# 注意：这是为了消除 create-react-scripts 的报错
SKIP_PREFLIGHT_CHECK=true

# 例如：/Users/bob/<项目路径>/.blocklet-server server 任意的本地目录，建议设置到项目根目录下的 .blocklet-server 目录
ABT_NODE_DATA_DIR="<服务器数据目录>"

ABT_NODE_SESSION_SECRET="49bcf865c77a15993d87245b124bbc5125d2c3997437d1fda3"
ABT_NODE_SESSION_TTL="1d"
# 请使用以下代码自行生成 SK
# const { fromRandom } = require('@ocap/wallet')
# const ABT_NODE_SK = fromRandom().secretKey;
ABT_NODE_SK="<ABT_NODE_SK>"
ABT_NODE_PORT="3030"
ABT_NODE_MODE="production"
ABT_NODE_NAME="Blocklet 服务器（开发版）"
ABT_NODE_DESCRIPTION="用于管理你的 Blocklet 服务器的 Web 界面"
# 例如：http://192.168.1.2:3030 如果登录的时候无法扫码,请检查该设置
ABT_NODE_BASE_URL="http://<你的本地局域网 IP>:3030"

# 如果只想看 error 日志，设置 ABT_NODE_LOG_LEVEL 为 "error"
ABT_NODE_LOG_LEVEL="info"

# 关闭 SQLITE 日志。如果想查看 SQLITE 日志请注释掉 DISABLE_SQLITE_LOG
DISABLE_SQLITE_LOG=1

# 当且仅当,我们需要调试 npm run start:service 对应的前端的时候,才需要修改该配置(端口号为: 3040)
ABT_NODE_SERVICE_FE_PORT=""

```

3. 启动客户端和服务器

```shell

# 如果你不在 core/webapp 目录下
cd core/webapp

# 选项一
# 使用 4 个终端窗口分别启动

# 终端 0 => 数据库和消息队列
npm run start:hub
# 终端 1 => 服务器守护进程
npm run start:daemon
# 终端 2 => blocklet 服务
npm run start:service
# 终端 3 => 服务器仪表盘
npm run start:client


# 选项二
# 快速启动
npm run start

# 开发完成后，你可以使用 `npm run stop` 来彻底终止所有进程。
npm run stop
```

现在，你可以开始对 Blocklet 服务器进行开发了。

##### 启动 blocklet-service 客户端开发环境

如果你想开发 blocklet-service 客户端，还需要额外执行以下操作：

1. 在 `.env.development` 文件中设置 `ABT_NODE_SERVICE_FE_PORT="3040"`。
2. 按照上述相同的步骤启动客户端和服务器。
3. 启动 Blocklet 服务客户端。
4. 如果你要向 blocklet-service 添加新页面，请记得在浏览器中清除 service-worker 缓存。

```shell
cd core/blocklet-services
DEBUG=@abtnode/* npm run start:client
```

## 如何从本地源代码以生产模式运行？

> 以下步骤要求你已经正确设置了代码仓库，这意味着你可以在开发模式下启动仪表盘。

### 构建仪表盘

```shell
cd core/webapp && npm run build:client && npm run build:daemon
```

### 为 CLI 创建符号链接

```shell
ln -s /path/to/blocklet-server-repo/core/cli/bin/blocklet.js /usr/local/bin/bn
```

### 运行本地副本

```shell
# 可选：创建一个新实例用于测试
cd /path/to/你的空文件夹
bn server init

# 使用最新代码启动
bn server start
```

如果你的本地 Nginx 无法监听 80 端口和 443 端口，你可以让它监听其他端口：

```shell
ABT_NODE_HTTP_PORT=8080 ABT_NODE_HTTPS_PORT=8443 an start
```

然后，使用端口转发将流量从 80 重定向到 8080，从 443 重定向到 8443：

```shell
echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
" | sudo pfctl -ef -
```

### 运行端到端测试

```shell
# 在 core/webapp 目录下
yarn test:e2e
```

### 覆盖率

此软件包的覆盖率包含三个部分：

- api：使用 jest 收集，在 `jest.config.js` 中配置，结果在 `coverage-api` 中。
- src：使用 react-script 收集，在 `package.json` 的 `jest` 中配置，结果在 `coverage` 中。
- e2e：使用 cypress 收集，在 `package.json` 的 `nyc` 中配置，结果在 `coverage-e2e` 中。

### 在开发服务器中开发 blocklet

0. 确保你的开发服务器正在运行。
1. 进入 blocklet 根目录。
2. 运行命令 `<blocklet-server-source-dir>/core/cli/tools/dev.js`（将 `<blocklet-server-source-dir>` 替换为你自定义的文件夹）。

为 dev.js 创建一个链接：

1. 运行命令 `ln -s <blocklet-server-source-dir>/core/cli/tools/dev.js /usr/local/bin/bn-dev`。
2. 然后你可以使用 `bn-dev` 在开发服务器中开发 blocklet。

### 将 blocklet 部署到开发服务器

1. 在服务器仪表盘上创建一对访问密钥。
2. 进入 blocklet 根目录。
3. 打包你的 blocklet。
4. 部署到开发服务器：`bn deploy .blocklet/bundle --endpoint http://127.0.0.1:3030 --access-key <你的访问密钥> --access-secret <你的访问密钥机密>`。

### 为开发服务器运行迁移

```shell
cd core/webapp && npm run dev:migration -- --from-version <版本号>
```

例如：`npm run dev:migration -- --from-version 1.6.20` 将运行版本号大于 1.6.20 的迁移脚本。

### 配合 ux 仓库的热模块替换（HMR）使用

在 `.env.development` 文件中添加 `ARCBLOCK_UX_BASE_PATH`，其值等于你的 ux 仓库路径。

```shell
ARCBLOCK_UX_BASE_PATH="/Users/xxx/arcblock/ux"
```

然后，你可以修改 ux 仓库的源代码，在 blocklet-server web 应用中查看热模块替换的效果。

### 常见问题解答

问：使用 iOS 钱包或 Android 钱包连接开发服务器时收到 `URLSessionTask failed with error` 错误。

答：如果你的 .env、.env.development 或 .env.development.local 中存在 `ABT_NODE_BASE_URL`，请确保 `ABT_NODE_BASE_URL` 的值是你的本地局域网 IP。

问：如果在本地调试时，Cornerstone 应用程序界面显示应用程序正在运行，并且当你点击 Cornerstone 应用程序的 **打开** 按钮时，你被重定向到代理失败屏幕，或者代码安装屏幕，或者显示 `404` 或 `502` 错误的 blocklet 屏幕，请参考以下解决方案。

答：

解决方案一：关闭 blocklet-services 客户端 && 删除环境变量 ABT_NODE_SERVICE_FE_PORT && 重启 blocklet-service 进程：进入 webapp 目录并执行脚本 `npm run start:service`。

解决方案二：关闭所有与 blocklet-server 相关的开发进程，运行 `npm run deep-clean`，然后重启所有 blocklet-server 开发进程。
