Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions designer-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@opentiny/tiny-engine": "workspace:^",
"@opentiny/tiny-engine-meta-register": "workspace:^",
"@opentiny/tiny-engine-runtime-renderer": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"@opentiny/vue": "~3.20.0",
"@opentiny/vue-design-smb": "~3.20.0",
Expand Down
18 changes: 18 additions & 0 deletions designer-demo/public/opentiny-tinyengine-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions designer-demo/runtime.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/opentiny-tinyengine-logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Runtime Render</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/runtime.js"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions designer-demo/src/runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { initRuntimeRenderer } from '@opentiny/tiny-engine-runtime-renderer'

async function startApp() {
try {
await initRuntimeRenderer()
}
catch (error) {
//eslint-disable-next-line no-console
console.error('Failed to initialize runtime renderer:',error)
}
}

startApp()
Binary file added docs/solutions/imgs/runtime-designer-display.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/solutions/imgs/runtime-entry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/solutions/imgs/runtime-import-map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/solutions/imgs/runtime-runtime-display.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/solutions/imgs/runtime-runtime-display.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions docs/solutions/runtime-rendering-solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 运行时渲染器使用说明

---

## 前言
运行时渲染器用于在浏览器中直接渲染低代码 Schema,提供与“出码”并行的即时运行路径,可在设计阶段获得接近真实的交互与数据效果。

## 快速开始

### 环境准备
- 确保已拉取包含 runtime-renderer 包的新版本代码。
- 在项目根目录执行:
- `pnpm install` 安装依赖
- `pnpm run dev` 启动项目
或参考前后端联调[文档](https://opentiny.design/tiny-engine#/help-center/course/dev/debugging-of-java-backend)或[视频](https://www.bilibili.com/video/BV1TpZ5YqEKZ/?share_source=copy_web&vd_source=bed5a07195ea4a97bd9d6ccea9d8e3e3)来启动JAVA后端联调,获得更好的开发体验

### 启动运行时渲染器
- 在设计器界面,点击顶部工具栏的“运行时渲染”图标(见下图),系统会在新窗口中打开运行时页面。
![入口图标](./imgs/runtime-entry.png)
- 默认行为:
- 若当前正在编辑某页面,将自动路由至该页面;
- 若当前未编辑页面(如正在编辑区块),将自动跳转到首页。
- 在项目启动的情况下,直接在浏览器中输入正确的url也可以访问应用页面,无需点击图标入口

### 运行效果说明
下图为同一页面在设计器与运行时渲染器中的对比效果:

- 设计器效果
![设计器中效果](./imgs/runtime-designer-display.png)

- 运行时渲染器效果
![运行时渲染效果](./imgs/runtime-runtime-display.gif)

### URL 与路由说明

- 查询参数
- id:应用标识
- tenant:租户标识
- platform:平台标识
- 哈希路由
- 若当前正在编辑某页面,将自动路由至该页面,基于页面树中每个节点的 route 段,按祖先链拼接为 `#/<a>/<b>/<c>`。
- 若当前未编辑页面(如正在编辑区块),默认跳转应用首页。

- 入口地址
- 开发环境:`/runtime.html`
- 生产环境:`/runtime`

- 访问示例
- Dev: `http://localhost:8090/runtime.html?id=1&tenant=1&platform=1#/home`
- Prod: `https://your-host/runtime?id=1&tenant=1&platform=1#/home`

### 物料与依赖导入说明

当前运行时通过 bundle.json 读取物料包的 package 信息,支持从中读取用户添加的第三方物料依赖信息,无需额外手动导入。在资源管理中添加过cdn链接的npm包也无需额外引入。

如果第三方CDN包含子依赖,则需要手动在以下文件中补充 CDN 映射,支持完整cdn链接和包含占位符的格式:

- 文件路径:`packages/runtime-renderer/src/app-function/import-map.json`

示例:物料中使用 HUICharts 且其内部依赖 `echarts`,需为 `echarts` 在runtime-renderer 的 import-map.json 中添加映射:
```json
// filepath: packages/runtime-renderer/src/app-function/import-map.json
{
"imports": {
"echarts": "${VITE_CDN_DOMAIN}/echarts${versionDelimiter}5.4.1${fileDelimiter}/dist/echarts.esm.js"
},
"importStyles": {}
}
```
37 changes: 19 additions & 18 deletions packages/build/vite-config/src/canvas-dev-external.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import vitePluginExternalize from 'vite-plugin-externalize-dependencies'
import { genImportMapPlugin } from './vite-plugins/genImportMapOnly.js'
export function canvasDevExternal(override = {}) {
const prefix = '/node_modules/@opentiny/tiny-engine'

// 以下内容由于区块WebComponent加载需要补充
const blockRequire = {
externals: [/^@opentiny\/vue$/, /^@opentiny\/vue-icon$/],
export const prefix = '/node_modules/@opentiny/tiny-engine'
export const dependencies = {
base: {
imports: {
'@opentiny/vue': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-pc.mjs`,
'@opentiny/vue-icon': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-icon.mjs`
vue: `${prefix}/node_modules/vue/dist/vue.runtime.esm-browser.js`,
'vue-i18n': `${prefix}/node_modules/vue-i18n/dist/vue-i18n.esm-browser.js`
},
importStyles: [`${prefix}/node_modules/@opentiny/vue-theme/index.css`]
}
// 以下内容由于物料协议不支持声明子依赖而@opentiny/vue需要依赖所以需要补充
const tinyVueRequire = {
externals: [/^vue$/, /^vue-i18n$/]
},
ui: {
imports: {
'@opentiny/vue': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-pc.mjs`,
'@opentiny/vue-icon': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-icon.mjs`,
'@opentiny/vue-common': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-common.mjs`,
'@opentiny/vue-locale': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-locale.mjs`
}
},
externals: [/^@opentiny\/vue$/, /^@opentiny\/vue-icon$/, /^@opentiny\/vue-common$/, /^@opentiny\/vue-locale$/],
importStyles: [`${prefix}/node_modules/@opentiny/vue-theme/index.css`]
}
}
export function canvasDevExternal(override = {}) {
return [
vitePluginExternalize({ externals: [/^vue$/, /^vue-i18n$/, ...blockRequire.externals] }),
vitePluginExternalize({ externals: [...dependencies.base.externals, ...dependencies.ui.externals] }),
genImportMapPlugin(
{
imports: {
vue: `${prefix}/node_modules/vue/dist/vue.runtime.esm-browser.js`,
'vue-i18n': `${prefix}/node_modules/vue-i18n/dist/vue-i18n.esm-browser.js`,
...blockRequire.imports,
...tinyVueRequire.imports,
...dependencies.base.imports,
...dependencies.ui.imports,
...override
}
},
[...blockRequire.importStyles]
[...dependencies.ui.importStyles]
)
]
}
10 changes: 8 additions & 2 deletions packages/build/vite-config/src/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
import { getBaseUrlFromCli, copyBundleDeps, importMapLocalPlugin } from './localCdnFile/index.js'
import { devAliasPlugin } from './vite-plugins/devAliasPlugin.js'
import { htmlUpgradeHttpsPlugin } from './vite-plugins/upgradeHttpsPlugin.js'
import { canvasDevExternal } from './canvas-dev-external.js'
import { treeShakingPlugin } from './vite-plugins/treeShakingPlugin.js'
import { canvasDevExternal } from './canvas-dev-external.js'
import { runtimeExternal } from './runtime-external.js'

const monacoEditorPlugin = monacoEditorPluginCjs.default
const nodeGlobalsPolyfillPlugin = nodeGlobalsPolyfillPluginCjs.default
Expand Down Expand Up @@ -104,7 +105,8 @@ const getDefaultConfig = (engineConfig) => {
plugins: [nodePolyfill({ include: null })], // 使用@rollup/plugin-inject的默认值{include: null}, 即在所有代码中生效
input: {
index: path.resolve(process.cwd(), './index.html'),
preview: path.resolve(process.cwd(), './preview.html')
preview: path.resolve(process.cwd(), './preview.html'),
runtime: path.resolve(process.cwd(), './runtime.html')
},
output: {
manualChunks: (id) => {
Expand Down Expand Up @@ -187,5 +189,9 @@ export function useTinyEngineBaseConfig(engineConfig) {
config.plugins.push(canvasDevExternal())
}

if (engineConfig.useSourceAlias && command !== 'serve') {
config.plugins.push(runtimeExternal())
}

return config
}
84 changes: 84 additions & 0 deletions packages/build/vite-config/src/runtime-external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { dependencies } from './canvas-dev-external.js'

/**
* 嵌入<script type="importmap">到html头部,并且使用ViteConfig.build.rollupOptions.external排除importmap声明的依赖构建
* @param {*} importmap <script type="importmap">的结构
* @param {Array<string>} importMapStyles css样式文件url
* @returns
*/
export function genHtmlImportmapPlugin({ importmap, importStyles = [], externals = [] }) {
const isException = (source, _importer, _isResolved) => {
for (const external of externals) {
if (external.test(source)) {
return true
}
}
return false
}
return {
name: 'vite-plugin-importmap-runtime',
config() {
return {
build: {
rollupOptions: {
external: (source, importer, isResolved) => {
return isException(source, importer, isResolved)
},
output: {
preserveModuleImports: true,
// 若需兼容非 ESM 环境(如 UMD),可配置 globals(仅备用)
globals: Object.keys(importmap.imports).reduce((prev, cur) => {
prev[cur] = cur
return prev
}, {})
}
}
}
}
},
transformIndexHtml: {
order: 'pre',
handler(html, _ctx) {
return {
html,
tags: [
{
tag: 'script',
attrs: {
type: 'importmap'
},
children: JSON.stringify(importmap, null, 2),
injectTo: 'head-prepend'
},
...importStyles.map((url) => ({
tag: 'link',
attrs: {
rel: 'stylesheet',
href: url
},
injectTo: 'head-prepend'
}))
]
}
}
}
}
}

export function runtimeExternal(override = {}) {
const scripts = {
...dependencies.base.imports,
...dependencies.ui.imports,
...override
}
const styles = [...dependencies.ui.importStyles]
return [
genHtmlImportmapPlugin({
importmap: {
imports: { ...scripts }
},
importStyles: [...styles],
externals: [...dependencies.base.externals, ...dependencies.ui.externals]
})
]
}
2 changes: 2 additions & 0 deletions packages/build/vite-config/src/vite-plugins/devAliasPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ const getDevAlias = (useSourceAlias) => {
'@opentiny/tiny-engine-toolbar-logo': path.resolve(basePath, 'packages/toolbars/logo/index.ts'),
'@opentiny/tiny-engine-toolbar-media': path.resolve(basePath, 'packages/toolbars/media/index.ts'),
'@opentiny/tiny-engine-toolbar-preview': path.resolve(basePath, 'packages/toolbars/preview/index.ts'),
'@opentiny/tiny-engine-runtime-renderer': path.resolve(basePath, 'packages/runtime-renderer/index.ts'),
'@opentiny/tiny-engine-toolbar-generate-code': path.resolve(basePath, 'packages/toolbars/generate-code/index.ts'),
'@opentiny/tiny-engine-toolbar-refresh': path.resolve(basePath, 'packages/toolbars/refresh/index.ts'),
'@opentiny/tiny-engine-toolbar-redoundo': path.resolve(basePath, 'packages/toolbars/redoundo/index.ts'),
'@opentiny/tiny-engine-toolbar-clean': path.resolve(basePath, 'packages/toolbars/clean/index.ts'),
'@opentiny/tiny-engine-toolbar-theme-switch': path.resolve(basePath, 'packages/toolbars/themeSwitch/index.ts'),
'@opentiny/tiny-engine-toolbar-runtime-deploy': path.resolve(basePath, 'packages/toolbars/runtime-deploy/index.ts'),
'@opentiny/tiny-engine-toolbar-save': path.resolve(basePath, 'packages/toolbars/save/index.ts'),
'@opentiny/tiny-engine-toolbar-setting': path.resolve(basePath, 'packages/toolbars/setting/index.ts'),
'@opentiny/tiny-engine-toolbar-collaboration': path.resolve(basePath, 'packages/toolbars/collaboration/index.ts'),
Expand Down
Loading