Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: split renderer #888

Draft
wants to merge 30 commits into
base: refactor/develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8055d3c
refactor: split renderer package
yy-wow Oct 24, 2024
e12ae04
fix: miss file
yy-wow Oct 24, 2024
80b514e
refactor: split renderer package
yy-wow Oct 30, 2024
eec6840
fix: import path
yy-wow Oct 30, 2024
b6df90b
fix: remove unused api
yy-wow Oct 30, 2024
2b692b2
feat: 增加画布特征判断
yy-wow Oct 30, 2024
a1778ad
fix: builtin name
yy-wow Oct 30, 2024
c76693b
fix: package.json
yy-wow Oct 30, 2024
391069c
fix: viteConfig
yy-wow Oct 30, 2024
d3ff581
fix: viteConfig
yy-wow Oct 30, 2024
965730b
fix: review
yy-wow Oct 30, 2024
3f7efcd
doc: README
yy-wow Oct 30, 2024
a9c5c65
fix: README
yy-wow Nov 1, 2024
948b741
fix: 渲染器接收参数
yy-wow Nov 4, 2024
2f96bf3
doc: update README
yy-wow Nov 4, 2024
3658f57
doc: update README
yy-wow Nov 4, 2024
a37a30b
fix: package dependencies
yy-wow Nov 4, 2024
cff6056
Merge branch 'refactor/develop' into refactor/split-renderer
yy-wow Nov 5, 2024
88dcaa0
fix: build error
yy-wow Nov 5, 2024
f75edeb
Merge branch 'refactor/develop' into refactor/split-renderer
yy-wow Nov 8, 2024
23028c7
Merge branch 'refactor/develop' into refactor/split-renderer
yy-wow Nov 11, 2024
622f4ca
fix: revert canvasFlag
yy-wow Nov 11, 2024
c370fbf
fix: remove props
yy-wow Nov 11, 2024
0097246
fix: README
yy-wow Nov 11, 2024
af1dc68
Merge branch 'refactor/develop' into refactor/split-renderer
yy-wow Nov 13, 2024
40d3b16
feat: add generate context function
yy-wow Nov 14, 2024
1eac4d0
feat: export generateContext
yy-wow Nov 15, 2024
8a17eb5
fix: generate context
yy-wow Nov 15, 2024
ee61ad6
fix: state reactive
yy-wow Nov 22, 2024
e629c68
fix: vite config
yy-wow Nov 22, 2024
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 jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"@opentiny/tiny-engine": ["packages/design-core/index.js"],
"@opentiny/tiny-engine-meta-register": ["packages/register/src/index.js"],
"@opentiny/tiny-engine-canvas": ["packages/canvas/src/index.js"],
"@opentiny/tiny-engine-renderer": ["packages/renderer/src/index.js"],
"@opentiny/tiny-engine-plugin-materials": ["packages/plugins/materials/index"],
"@opentiny/tiny-engine-plugin-state": ["packages/plugins/state/index"],
"@opentiny/tiny-engine-plugin-script": ["packages/plugins/script/index"],
Expand Down
8 changes: 0 additions & 8 deletions mockServer/src/mock/get/app-center/v1/apps/schema/918.json
Original file line number Diff line number Diff line change
Expand Up @@ -2130,14 +2130,6 @@
"main": ""
}
},
{
"name": "npm",
"type": "function",
"content": {
"type": "JSFunction",
"value": "''"
}
},
{
"name": "Pager",
"type": "npm",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const getDevAlias = (useSourceAlias) => {
'@opentiny/tiny-engine-http': path.resolve(basePath, 'packages/http/src/index.js'),
'@opentiny/tiny-engine-canvas': path.resolve(basePath, 'packages/canvas/index.js'),
'@opentiny/tiny-engine-canvas/render': path.resolve(basePath, 'packages/canvas/render/index.js'),
'@opentiny/tiny-engine-renderer': path.resolve(basePath, 'packages/renderer/src/index.js'),
'@opentiny/tiny-engine-utils': path.resolve(basePath, 'packages/utils/src/index.js'),
'@opentiny/tiny-engine-webcomponent-core': path.resolve(basePath, 'packages/webcomponent/src/lib.js'),
'@opentiny/tiny-engine-i18n-host': path.resolve(basePath, 'packages/i18n/src/lib.js'),
Expand Down
2 changes: 1 addition & 1 deletion packages/canvas/container/src/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from '../../common'
import { useCanvas, useLayout, useResource, useTranslate, useMaterial } from '@opentiny/tiny-engine-meta-register'
import { isVsCodeEnv } from '@opentiny/tiny-engine-common/js/environments'
import Builtin from '../../render/src/builtin/builtin.json' //TODO 画布内外应该分开
import { Builtin } from '@opentiny/tiny-engine-renderer'

export const POSITION = Object.freeze({
TOP: 'top',
Expand Down
7 changes: 4 additions & 3 deletions packages/canvas/render/src/lowcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

import { getCurrentInstance, nextTick, provide, inject } from 'vue'
import { I18nInjectionKey } from 'vue-i18n'
import { api } from './RenderMain'
import { collectionMethodsMap, generateFn, globalNotify } from './render'
import { api } from '@opentiny/tiny-engine-renderer'

const { getCollectionMethodsMap, generateFn, globalNotify } = api

export const lowcodeWrap = (props, context) => {
const global = {}
Expand Down Expand Up @@ -61,7 +62,7 @@ export const lowcodeWrap = (props, context) => {
const fnName = fn.name
if (fn.toString().includes('return this')) {
return () => global
} else if (fnName && collectionMethodsMap[fnName.slice(0, -1)]) {
} else if (fnName && getCollectionMethodsMap()[fnName.slice(0, -1)]) {
// 这里区块打包的时候会在方法名称后面多加一个字符串,所以此处需要截取下函数名称
fn.realName = fnName.slice(0, -1)
return generateFn(fn)
Expand Down
2 changes: 1 addition & 1 deletion packages/canvas/render/src/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import { createApp } from 'vue'
import { addScript, addStyle, dynamicImportComponents, updateDependencies } from '../../common'
import TinyI18nHost, { I18nInjectionKey } from '@opentiny/tiny-engine-common/js/i18n'
import Main, { api } from './RenderMain'
import Main, { api } from '@opentiny/tiny-engine-renderer'
yy-wow marked this conversation as resolved.
Show resolved Hide resolved
import lowcode from './lowcode'
import { supportUmdBlock } from './supportUmdBlock'

Expand Down
6 changes: 5 additions & 1 deletion packages/canvas/render/src/supportUmdBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import * as TinyVueIcon from '@opentiny/vue-icon'
import TinyVue from '@opentiny/vue'
import TinyI18nHost from '@opentiny/tiny-engine-common/js/i18n'
import { camelize, capitalize } from '@vue/shared'
import { blockSlotDataMap, getComponent } from './render'
import { api } from '@opentiny/tiny-engine-renderer'

const { getBlockSlotDataMap, getComponent } = api

// 和 @opentiny/tiny-engine-block-build 打包umd方式相适配
export function supportUmdBlock() {
Expand Down Expand Up @@ -33,6 +35,8 @@ export function supportUmdBlock() {

// 如果是作用域插槽,则获取作用域插槽传递过来的参数
if (slotData) {
const blockSlotDataMap = getBlockSlotDataMap()

yy-wow marked this conversation as resolved.
Show resolved Hide resolved
if (blockSlotDataMap[blockName]) {
blockSlotDataMap[blockName][slotName] = slotData
} else {
Expand Down
42 changes: 42 additions & 0 deletions packages/renderer/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* 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.
*
*/

module.exports = {
env: {
browser: true,
es2015: true,
node: true,
jest: true
},
extends: ['eslint:recommended', 'plugin:vue/vue3-essential'],
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@babel/eslint-parser',
ecmaVersion: 'latest',
sourceType: 'module',
requireConfigFile: false,
babelOptions: {
parserOpts: {
plugins: ['jsx']
}
}
},
plugins: ['vue'],
rules: {
'no-console': 'error',
'no-debugger': 'error',
'space-before-function-paren': 'off',
'vue/multi-word-component-names': 'off',
'no-use-before-define': 'error',
'no-unused-vars': ['error', { ignoreRestSiblings: true, varsIgnorePattern: '^_', argsIgnorePattern: '^_' }]
}
}
24 changes: 24 additions & 0 deletions packages/renderer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
36 changes: 36 additions & 0 deletions packages/renderer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# tiny-engine-canvas

## build

Note: tiny-engine-canvas module contains two parts, *canvas-container* and *canvas*, and canvas is rendered in iframe window
During the build phase, they are built separately. The build products use different external strategies, and the *canvas* product will be embedded in base64 format within the *canvas-container* product,
since the library-mode-build now only supports embed dependent assets in base64 format, and the embedded base64 format is more general for other build and pack tools.
You should notice the difference between the products of *canvas-container* and *canvas*. The product of *canvas-container* works fine with other *tiny-engine-\** packages with unfixed versions. The product of *canvas* only externalizes `vue` and `vue-i18n`; the rest of the dependent packages will be packed and won't be replaceable with other versions. (This means you will not be able to joint-debug the dependent packages inside the *canvas* product code. You should joint-debug using the canvas module source code.)

Develop and debug the canvas module in development mode requires:

1) Setting the Vite config with `devAlias` (`resolve.alias`), which points the canvas package name to the canvas module source code.
2) Using the `canvas-dev-external` plugin.

Vite uses esbuild in development. The `devAlias` configuration makes the source code of the canvas module work and allows for joint debugging.
However, esbuild won't perceive the external configuration for rollup; it will resolve `vue` and other dependencies (that we originally wanted to exclude and let them naturally point to the package addresses in the `importmap`) to `node_modules`.
For this reason, we need the `canvas-dev-external` plugin. It can externalize the dependencies specified in the `importmap` of *canvas* for esbuild.
On the other hand, externalizing the dependencies will affect all other packages in the same runtime. This plugin will generate another `importmap` that points all affected dependencies to `node_modules` to eliminate the side effects.

Finally, modules inside and outside the *canvas* iframe can joint-debug well, and we accomplish the goal of decoupling the versions of `vue` and other dependencies inside and outside the *canvas*. (That is, we can use completely different versions of `vue` inside or outside the *canvas*; we don’t need to synchronize the versions.
In some cases, we may want to use a lower or higher version for better support.)

yy-wow marked this conversation as resolved.
Show resolved Hide resolved
## 构建

注意: tiny-engine-canvas模块目前含有两部分,*画布容器*和*画布*, 其中*画布*在iframe内进行渲染。
在构建阶段canvas包使用分开构建,在构建完的产物中,*画布容器*和*画布*使用了不同的external策略,打包完后*画布*源码会base64内嵌到*画布容器*源码中。
目前库打包依赖资源仅支持base64,且base64内嵌普适性较高,在其他非vite打包工具下能正常工作。
所以使用canvas包产物应该注意到,*画布容器*打包后仍然可以和其他*tiny-engine-\**的包的不同版本配合工作,而*画布*本身打包完后内容就固化了,不会再和其他包联动。

开发态开发和调试canvas包需要:
1) vite配置中 devAlias(`resolve.alias`)将canvas包名指向canvas的src源码
2) 搭配canvas-dev-external插件使用
当前开发态vite使用了esbuild, devAlias配置将能正常工作和联调, 但是esbuild不接收来自rollup配置的externals,将导致原本画布应该走`importmap`解析的内容指向了`node_modules`,
故需要搭配canvas-dev-external插件,一方面将*画布*的external项排除,另一方面,对*画布*外也造成的影响将通过另一个指向`node_modules`的`importmap`进行补偿

最后,通过以上方式,画布内外能够很好地联调,并且完成了画布内外vue版本的解耦(即可以支持使用完全不同的vue版本)
61 changes: 61 additions & 0 deletions packages/renderer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@opentiny/tiny-engine-renderer",
"version": "2.0.0-alpha.4",
"publishConfig": {
"access": "public"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"main": "dist/index.js",
"module": "dist/index.js",
"files": [
"dist"
],
"exports": {
".": {
"import": "./dist/index.js"
}
},
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
"directory": "packages/canvas"
},
yy-wow marked this conversation as resolved.
Show resolved Hide resolved
"bugs": {
"url": "https://github.com/opentiny/tiny-engine/issues"
},
"author": "OpenTiny Team",
"license": "MIT",
"homepage": "https://opentiny.design/tiny-engine",
"type": "module",
"dependencies": {
"@babel/core": "7.18.13",
"@opentiny/tiny-engine-builtin-component": "workspace:*",
"@opentiny/tiny-engine-common": "workspace:*",
"@opentiny/tiny-engine-http": "workspace:*",
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-meta-register": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"@opentiny/tiny-engine-webcomponent-core": "workspace:*",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/shared": "^3.3.4",
"@vueuse/core": "^9.6.0"
},
yy-wow marked this conversation as resolved.
Show resolved Hide resolved
"devDependencies": {
"@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*",
"@vitejs/plugin-vue": "^5.1.2",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"rollup-plugin-polyfill-node": "^0.13.0",
"vite": "^5.4.2"
},
"peerDependencies": {
"@opentiny/vue": "^3.14.0",
"@opentiny/vue-icon": "^3.14.0",
"@opentiny/vue-renderless": "^3.14.0",
"vue": "^3.4.15",
"vue-i18n": "^9.9.0"
}
}
14 changes: 14 additions & 0 deletions packages/renderer/src/CanvasEmpty.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<p class="empty-text">从左侧面板拖入组件,以构建页面</p>
</template>

<style lang="less" scoped>
.empty-text {
position: absolute;
top: 250px;
left: 50%;
transform: translate(-50%);
color: #808080;
font-size: 12px;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ import TinyVue from '@opentiny/vue'
import * as TinyVueIcon from '@opentiny/vue-icon'
import { useBroadcastChannel } from '@vueuse/core'
import { constants, utils as commonUtils } from '@opentiny/tiny-engine-utils'
import renderer, { parseData, setConfigure, setController, globalNotify, isStateAccessor } from './render'
import renderer, {
parseData,
setConfigure,
setController,
globalNotify,
isStateAccessor,
generateFn,
getCollectionMethodsMap,
getBlockSlotDataMap,
getComponent
} from './render'
import {
getNode as getNodeById,
clearNodes,
Expand All @@ -27,7 +37,9 @@ import {
getCondition,
getConditions,
context,
setNode
setNode,
getCanvasFlag,
setCanvasFlag
} from './context'
import CanvasEmpty from './CanvasEmpty.vue'

Expand Down Expand Up @@ -356,6 +368,7 @@ const setSchema = async (data) => {

const getNode = (id, parent) => (id ? getNodeById(id, parent) : schema)

// 设置自定义渲染器
let canvasRenderer = null

const defaultRenderer = function () {
Expand Down Expand Up @@ -451,5 +464,12 @@ export const api = {
setGlobalState,
setNode,
getRenderer,
setRenderer
setRenderer,
globalNotify,
generateFn,
getCollectionMethodsMap,
getBlockSlotDataMap,
getComponent,
getCanvasFlag,
setCanvasFlag
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*
*/

import { getController } from '../render'
import { api } from '../RenderMain'
import { useModal } from '@opentiny/tiny-engine-meta-register'

Expand Down Expand Up @@ -45,7 +44,7 @@ const genRemoteMethodToLifeSetup = (variableName, sourceRef, pageSchema) => {
const removeState = (pageSchema, variableName) => {
delete pageSchema.state[variableName]

const { parse, traverse, generate } = getController().ast
const { parse, traverse, generate } = api.getController().ast
const setupFn = pageSchema.lifeCycles?.setup?.value

try {
Expand Down Expand Up @@ -76,7 +75,7 @@ const defaultHandlerTemplate = ({ node, sourceRef, schemaId, pageSchema }) => {
const genVarName = (schemaId) => `${NAME_PREFIX.loop}${schemaId}`

const updateNode = () => {
const { configure } = getController().getMaterial(node?.componentName)
const { configure } = api.getController().getMaterial(node?.componentName)

if (!configure?.loop) {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

<script>
import { ref, watch, computed, inject } from 'vue'
import { getController } from '../render'
import { api } from '../RenderMain'
import CanvasPlaceholder from './CanvasPlaceholder.vue'

import { getHandler } from './CanvasCollection.js'

export const fetchDataSourceDetail = (dataSourceId) =>
getController().request.get(`/app-center/api/sources/detail/${dataSourceId}`) // TODO: 强行耦合了
api.getController().request.get(`/app-center/api/sources/detail/${dataSourceId}`) // TODO: 强行耦合了
yy-wow marked this conversation as resolved.
Show resolved Hide resolved

export default {
components: {
Expand Down
3 changes: 3 additions & 0 deletions packages/renderer/src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const NODE_UID = 'data-uid'
export const NODE_TAG = 'data-tag'
export const NODE_LOOP = 'loop-id'
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const context = shallowReactive({})
export const conditions = shallowReactive({})

const nodes = {}
let canvasFlag = true // 是否表现画布内特征的标志,如拖拽事件、原生事件是否触发等

export const setNode = (schema, parent) => {
schema.id = schema.id || utils.guid()
Expand Down Expand Up @@ -55,3 +56,9 @@ export const setCondition = (id, visible = false) => {
export const getCondition = (id) => conditions[id] !== false

export const getConditions = () => conditions

export const getCanvasFlag = () => canvasFlag

export const setCanvasFlag = (flag) => {
canvasFlag = flag
}
yy-wow marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading