TinyEngine 低代码引擎区块局域网部署方案全新上线!

本文由体验技术团队 TinyEngine 项目组成员创作~

在 TinyEngine 开源后,对私有化部署存在诉求的用户越来越多,而当前 TinyEngine 多项内容都依托在公网中,当前官网提供的区块发布方案,为公网环境下的发布,不能完全满足部分用户的需求。因此需要提供用户能够在内网环境下,也能够正常使用 TinyEngine 的全部功能的方案。

现在提出区块发布私有化的两种解决方案给用户自行选择:

  • 将区块发布到 npm 私仓中,搭建内部的 unpkg 和私仓环境
  • 将区块发布到数据库中,从库中直接读取区块产物。

推荐使用第一种方式,因为采用私仓的方式能尽可能保留我们当前的模式,以及能够使用区块版本浮动功能,并且在我们基础物料组件库中,我们也能将组件库上传到私仓里,达到基础物料的私有化。

注:

  • 搭建 unpkg:基于开源 unpkg(github.com/mjackson/un... 在公司内部搭建 npm 的 cdn 环境

  • 私仓环境:在公司内部搭建一个私有的 npm registry,提供发布和拉取能力。

方案一

将区块发布到npm私仓中

一、安装 verdaccio

当前业界内存在很多搭建 npm 私仓的方案,如: verdaccio, neuxs, cnpmjs 等,大家可以自行选择。在此以使用 verdaccio 为例,可以查看 verdaccio 官网文档或者相关学习文档来安装使用 verdaccio ,在这里只做简单介绍。

1.1 verdaccio 安装

本地直接通过 npm下载

复制代码
npm install verdaccio

本地启动

复制代码
verdaccio

或者使用 pm2 启动

bash 复制代码
# 启动 verdaccio
pm2 start ./verdaccio
# 查看进程
pm2 log verdaccio 

虚拟机可以通过 docker 拉取镜像

js 复制代码
docker pull verdaccio/verdaccio

启动

js 复制代码
docker run -it  -p 4873:4873 verdaccio/verdaccio

(线上使用请配置数据持久保存,以免数据丢失。)

1.2 注册用户

js 复制代码
npm login --registry=http://localhost:4873/

1.3 创建 token,此 token 替换原 npm 上申请的 token,用于发包

js 复制代码
npm token create --registry=http://localhost:4873/

token 生成完后,需要配置到环境变量NPM_AUTH_TOKEN中,后续 webService 会使用;本地运行时的配置:

vi ~/.bashrc

js 复制代码
export NPM_AUTH_TOKEN=xxxx  # 填入刚生成的token

设置完后,重新打开命令行或在当前命令行执行以下命令,让设置的环境变量生效。(git bash 中设置的环境变量无法适用于 powershell 和 cmd )

source ~/.bashrc

1.4 安装后验证

在安装并完成测试后, 访问 http://localhost:4873/ ,在 verdaccio 的管理界面能看到发布上去的 npm 包表示安装成功。

建议发布的测试包名称格式:@公司码/组件名,以便于后续搭建 unpkg 时测试使用。以下是测试用的 package.json 供参考:

发布完成后, 访问 http://localhost:4873/ ,在 verdaccio 的管理界面能看到发布上去的 npm 包表示安装成功。

二、安装 unpkg

在 verdaccio 安装好后,TinyEngine 的包已经能够正常发布在私仓上,如果想要在 TinyEngine 的页面上去获取到私仓里的包,正确的显示区块,这里还需要借助 unpkg 去获取到包的数据,而由于公网的 unpkg 无法直接读取 npm 私仓里的包,因此还需要搭建自己的 unpkg 服务器,结合私有的 unpkg,才能在 TinyEngine 的页面上显示你所建的区块。

unpkg的搭建,大家可以自行在网上参考相关文档,将官方的 unpkg 源码下载下来,进行改造,也可以参考别人的成功案例。改造成功后,访问 http://localhost:8080/ 能看到 unpkg 服务启动成功。

然后访问之前发布的测试包: http://localhost:8080/@公司码/组件名 ,如能显示 js 文件内容, 则表示 unpkg 安装成功。

三、修改 tiny-engine-webservice

3.1 修改 app/service/material-center/blockBuilder.ts 的 代码

js 复制代码
public unpkgBaseUrl = 'http://localhost:8080'; // 修改为unpkg服务的ip端口
js 复制代码
generatePackageJson(blockInfo, version) {
        let { label, id } = blockInfo
        label = label.replace(/\W|_/g, '').toLocaleLowerCase() || 'default'
        const name = `@opentiny-assets/tinyengine-block-${label}-${id}` // 修改点:发包的名称根据自己情况更改, @opentiny-assets改成 @用户的公司码
        this.pkgName = name
        return {
        name,
        version,
        description: '',
        main: `js/web-component.es.js`,  // 修改点:main 必须是 js/web-component.es.js , 否则 unpkg 无法读取到 js 文件
        keywords: [],
        author: '',
        license: 'ISC'
        }
    }

3.2 修改 config.default.ts 的代码

替换 registry 为自己的私仓地址

js 复制代码
config.registry = 'http://127.0.0.1:4873/'; // 修改点:替换为自己的私仓地址

注意: 在1.3小节里,已经生成了 npm token,写入到了NPM_AUTH_TOKEN环境变量。因此本文件中authToken的赋值就不用再修改了,若是没有更换的话,记得参考1.3小节,去替换你的环境变量。

3.3 修改 app/service/cnpm.ts 的代码

去掉 --access=public

js 复制代码
  async publishCnpm(packagePath) {
    const commands = ['npm publish']; // 修改点:去掉原先的--access=public
    return this.ctx.helper.execCommandWithCatch(commands, { cwd: packagePath }, 'publish cnpm');
  }

四、在 TinyEngine 中发布区块

以上步骤完成后,可以启动 tiny-engine 进行区块发布测试。验证过程中可以通过查看 tiny-engine-webservice 的发布过程排查问题,TinyEngine 会生成组件包:

然后发布到私仓:

发布完成之后,可以打开 http://localhost:4873/ 验证是否发布成功

并且查看本地启动的 unpkg,是否能够正常访问刚才发布的区块。

验证完成后,可以在物料中把刚才发布的区块进行添加,添加完毕后就可以正常的使用区块功能。

五、服务部署

当前步骤都是在电脑本地环境下运行调试的,在本地验证正确后,可以自行部署到服务器中。实际生产部署模式以企业、组织内部具体情况具体分析,具体安装以及启动操作流程都跟本地一致,可能会有安装目录位置的差异。

方案二

将区块发布到数据库

一、方案目的

原有的区块托管于 npm,通过 cdn 获取已发布区块内的文件,如果没有公网环境,且不使用私仓的情况下,为区块的托管提供数据库托管方案,使得区块的使用不在依赖于公网环境和 cdn

二、设计思路

三、简单demo,仅供参考

1. 新增存储数据库的表,字段如下:

id int(10) 自增id
file_name varchar(255) 文件名
package_name varchar(255) 包名
file_content longtext 文件内容
version varchar(255) 版本
created_at timestamp 创建时间
updated_at timestamp 更新时间

strapi 生成表可以在管理面板创建,也可以在 tiny-engine-data-center 服务根目录 api 文件夹下自己编辑代码,无需手动在 mysql 创建表

js 复制代码
  {
  "kind": "collectionType",
  "collectionName": "block_file_store",
  "info": {
    "name": "block-file-store",
    "description": ""
  },
  "options": {
    "increments": true,
    "timestamps": true
  },
  "attributes": {
    "package_name": {
      "type": "string",
      "required": true
    },
    "file_name": {
      "type": "string",
      "required": true
    },
    "version": {
      "type": "string",
      "required": true
    },
    "file_content": {
      "type": "text",
      "required": true
    }
  }
}

2. 修改发布方法

config.default.ts 文件中新增配置

js 复制代码
config.dataBaseUrl = 'http://localhost:7011/material-center/api/block/read';

发布接口在文件夹路径/tiny-engine-webservice/app/service/material-center/blockBuilder.ts下,实现如下:

js 复制代码
private async publish(folder, blockInfo, version): Promise<any> {
    let { label, id } = blockInfo;
    label = (label as String).replace(/\W|_/g, '').toLocaleLowerCase() || 'default';
    const env = 'alpha'; // 视具体情况而定,可以从RUN_MODE环境变量取,也可以不使用
    const name = `@opentiny-assets/tinyengine-${env}-block-${label}-${id}`;
    this.pkgName = name;
    
    const prefix = `${this.config.dataBaseUrl}/${this.pkgName}@${version}`;
    const files = await globPromise(`**/*.*`, {
      cwd: folder
    });
    for(const file of files){
      const fileContent = await fs.readFile( path.join(folder, file));
      // 文件转二进制
      const base64Data = fileContent.toString('base64');
      const filename = file.substring(file.lastIndexOf('/') + 1);
      // 存储数据库
      await this.service.material.blockFilesStore.create({
        package_name: name,
        file_name: filename,
        version: version,
        file_content: base64Data
       });
     }
    return this.filterFiles(files, prefix);
  }

3. 新增后端获取区块产物 api 接口:

3.1 接口

Method URI Description
GET material-center/api/block/read/ 根据区块链接信息读取文件
3.1.1 请求 request
Name Mandatory Type position Description
file_name M string body 文件名
version M string body 版本
package_name M string body 包名
3.1.2 响应 Response
Name Mandatory Type Description
data O object 响应数据实体

router/materialCenter/base.ts 新增路由:

js 复制代码
// 路由获取文件链接读取文件
subRouter.get('/block/read/*', controller.materialCenter.block.readFileContentLink);

4、接口实现

js 复制代码
async readFileContentLink(){
    const params = this.ctx.params;
    const paramTemp = params[0];
    const filename = paramTemp.substring(paramTemp.lastIndexOf('/') + 1);
    const versionRegex = /@([\d.]+)/;
    const version = paramTemp.match(versionRegex)? paramTemp.match(versionRegex)[1]:null;
    const package_name = '@' + paramTemp.split('@')[1];
    const paramTemps =
    {
      file_name: filename,
      version: version,
      package_name: package_name

    }
    const res = await this.service.materialCenter.blockFileStore.find(paramTemps);
    this.ctx.type = 'text/javascript';
    this.ctx.body = Buffer.from(res.data[0]?.file_content, 'base64').toString('utf8');
  }

在 data-center 里 block-file-store/controller 下 block-file-store.js 新增根据文件名和包名查询最新一条的最高版本的文件信息的方法:

js 复制代码
module.exports = {
    async find(ctx) {
        const { fileName, packageName} = ctx.request.query;
        return strapi.services['block-file-store'].find({
            file_name: fileName,
            package_name: packageName,
            _sort: 'version:DESC',
            _limit: 1
        });
      }
};

5、效果展示

a.后端用 postman 调用访问文件链接效果如下:

b.在环境上部署后,新建区块,对区块进行发布后,将区块加入在物料中,在画布里使用区块时,会成功返回web-compnents.umd.js文件,并且与刚才发布的区块版本、包名一致,能够正确显示区块内容。

总结

当前介绍了两种方案的具体实现方式

  • 使用方案一可以最大的提高区块发布的灵活性,并且也可以使用版本浮动功能,但是代价就是需要搭建局域网内的私仓服务和 unpkg 服务;
  • 使用方案二数据库存托管的方式看似更加方便,但是可能会造成数据库存储的内容过于庞大。

大家可以根据实际情况选择最符合自己场景需求的方案,若是您有不同的想法或者建议,也欢迎您一起参与讨论,在这里(github.com/opentiny/ti...%25E7%2595%2599%25E4%25B8%258B%25E6%2582%25A8%25E5%25AE%259D%25E8%25B4%25B5%25E7%259A%2584%25E6%2580%259D%25E8%25B7%25AF%25E3%2580%2582 "https://github.com/opentiny/tiny-engine/discussions)%E7%95%99%E4%B8%8B%E6%82%A8%E5%AE%9D%E8%B4%B5%E7%9A%84%E6%80%9D%E8%B7%AF%E3%80%82")


感谢大家对 TinyEngine 低代码引擎的支持,感谢开发者欧阳同学的实战经验,助力 OpenTiny 共同探索更优质的解决方案。也希望后续有更多小伙伴一起加入 OpenTiny 的开源共建,让更多开发者受益~

相关推荐
一 乐21 分钟前
智慧党建|党务学习|基于SprinBoot+vue的智慧党建学习平台(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·学习
BBB努力学习程序设计1 小时前
CSS Sprite技术:用“雪碧图”提升网站性能的魔法
前端·html
BBB努力学习程序设计1 小时前
CSS3渐变:用代码描绘色彩的流动之美
前端·html
中杯可乐多加冰1 小时前
基于网易CodeWave智能开发平台构建宝可梦图鉴
深度学习·低代码·ai·数据分析·数据采集·无代码·网易codewave征文
冰暮流星1 小时前
css之动画
前端·css
jump6802 小时前
axios
前端
spionbo2 小时前
前端解构赋值避坑指南基础到高阶深度解析技巧
前端
用户4099322502122 小时前
Vue响应式声明的API差异、底层原理与常见陷阱你都搞懂了吗
前端·ai编程·trae
开发者小天2 小时前
React中的componentWillUnmount 使用
前端·javascript·vue.js·react.js
永远的个初学者3 小时前
图片优化 上传图片压缩 npm包支持vue(react)框架开源插件 支持在线与本地
前端·vue.js·react.js