Skip to content

Commit a7477a8

Browse files
authored
feat: materials new protocol (opentiny#940)
1 parent bf30f72 commit a7477a8

File tree

18 files changed

+298
-325
lines changed

18 files changed

+298
-325
lines changed

designer-demo/public/mock/bundle.json

Lines changed: 49 additions & 184 deletions
Large diffs are not rendered by default.

mockServer/src/mock/get/app-center/v1/apps/schema/918.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,8 @@
20922092
"value": "",
20932093
"package": "axios",
20942094
"destructuring": false,
2095-
"exportName": "axios"
2095+
"exportName": "axios",
2096+
"cdnLink": "https://unpkg.com/browse/axios@1.7.9/dist/esm/axios.min.js"
20962097
}
20972098
},
20982099
{

packages/canvas/DesignCanvas/src/DesignCanvas.vue

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,21 @@ export default {
6565
const canvasRef = ref(null)
6666
let showModal = false // 弹窗标识
6767
const { canvasSrc = '' } = getOptions(meta.id) || {}
68-
let canvasSrcDoc = ''
68+
const canvasSrcDoc = ref('')
6969
70-
if (!canvasSrc) {
71-
const { importMap, importStyles } = getImportMapData(getMergeMeta('engine.config')?.importMapVersion)
72-
canvasSrcDoc = initCanvas(importMap, importStyles).html
73-
}
70+
useMessage().subscribe({
71+
topic: 'init_canvas_deps',
72+
subscriber: 'canvas_design_canvas',
73+
callback: (deps) => {
74+
if (canvasSrc) {
75+
return
76+
}
77+
78+
const { importMap, importStyles } = getImportMapData(getMergeMeta('engine.config')?.importMapVersion, deps)
79+
80+
canvasSrcDoc.value = initCanvas(importMap, importStyles).html
81+
}
82+
})
7483
7584
const removeNode = (node) => {
7685
const { pageState } = useCanvas()
@@ -231,6 +240,11 @@ export default {
231240
})
232241
onUnmounted(() => {
233242
window.removeEventListener('popstate', postUrlChanged)
243+
244+
useMessage().unsubscribe({
245+
topic: 'init_canvas_deps',
246+
subscriber: 'canvas_design_canvas'
247+
})
234248
})
235249
236250
return {

packages/canvas/DesignCanvas/src/importMap.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { VITE_CDN_DOMAIN } from '@opentiny/tiny-engine-common/js/environments'
22

3-
export function getImportMapData(overrideVersions = {}) {
3+
export function getImportMapData(overrideVersions = {}, canvasDeps = { scripts: [], styles: [] }) {
44
const importMapVersions = Object.assign(
55
{
66
vue: '3.4.23',
@@ -32,16 +32,25 @@ export function getImportMapData(overrideVersions = {}) {
3232
}
3333
}
3434

35+
const materialsAndUtilsRequire = canvasDeps.scripts.reduce((imports, { package: pkg, script }) => {
36+
if (pkg && script) {
37+
imports[pkg] = script
38+
}
39+
40+
return imports
41+
}, {})
42+
3543
const importMap = {
3644
imports: {
3745
vue: `${VITE_CDN_DOMAIN}/vue@${importMapVersions.vue}/dist/vue.runtime.esm-browser.prod.js`,
3846
'vue-i18n': `${VITE_CDN_DOMAIN}/vue-i18n@${importMapVersions.vueI18n}/dist/vue-i18n.esm-browser.js`,
3947
...blockRequire.imports,
40-
...tinyVueRequire.imports
48+
...tinyVueRequire.imports,
49+
...materialsAndUtilsRequire
4150
}
4251
}
4352

44-
const importStyles = [...blockRequire.importStyles]
53+
const importStyles = [...blockRequire.importStyles, ...canvasDeps.styles]
4554

4655
return {
4756
importMap,

packages/canvas/common/src/utils.js

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,20 @@ export const copyObject = (node) => {
5656
}
5757

5858
/**
59-
* 动态导入组件,缓存组件对象
60-
* @param {object} param0 组件的依赖: { package: 包名,script:js文件cdn, components:组件id和导出组件名的映射关系}
59+
* 动态导入获取组件库模块
60+
* @param {*} pkg 模块名称
61+
* @param {*} script 模块的cdn地址
6162
* @returns
6263
*/
63-
export const dynamicImportComponents = async ({ package: pkg, script, components }) => {
64-
if (!script) return
64+
const dynamicImportComponentLib = async ({ pkg, script }) => {
65+
if (window.TinyComponentLibs[pkg]) {
66+
return window.TinyComponentLibs[pkg]
67+
}
68+
69+
if (!script) {
70+
return {}
71+
}
72+
6573
const href = window.parent.location.href || location.href // 这里要取父窗口的地址,因为在iframe中href是about:srcdoc
6674
const scriptUrl = script.startsWith('.') ? new URL(script, href).href : script
6775

@@ -71,27 +79,22 @@ export const dynamicImportComponents = async ({ package: pkg, script, components
7179
window.TinyComponentLibs[pkg] = modules
7280
}
7381

74-
Object.entries(components).forEach(([componentId, exportName]) => {
75-
const modules = window.TinyComponentLibs[pkg]
76-
77-
if (!window.TinyLowcodeComponent[componentId]) {
78-
window.TinyLowcodeComponent[componentId] = modules[exportName]
79-
}
80-
})
82+
return window.TinyComponentLibs[pkg]
8183
}
8284

8385
/**
84-
* 更新区块/组件依赖
85-
* @param {object} param0 依赖的CDN信息
86+
* 获取组件对象并缓存,组件渲染时使用
87+
* @param {object} param0 组件的依赖: { package: 包名,script:js文件cdn, components:组件id和导出组件名的映射关系}
88+
* @returns
8689
*/
87-
export const updateDependencies = ({ detail }) => {
88-
const { scripts = [], styles = [] } = detail || {}
89-
const { styles: canvasStyles } = window.thirdPartyDeps
90-
const newStyles = [...styles].filter((item) => !canvasStyles.has(item))
90+
export const getComponents = async ({ package: pkg, script, components }) => {
91+
if (!pkg) return
9192

92-
newStyles.forEach((item) => canvasStyles.add(item))
93+
const modules = await dynamicImportComponentLib({ pkg, script })
9394

94-
const promises = [...newStyles].map((src) => addStyle(src)).concat(scripts.map(dynamicImportComponents))
95-
96-
Promise.allSettled(promises)
95+
Object.entries(components).forEach(([componentId, exportName]) => {
96+
if (!window.TinyLowcodeComponent[componentId]) {
97+
window.TinyLowcodeComponent[componentId] = modules[exportName]
98+
}
99+
})
97100
}

packages/canvas/container/src/CanvasContainer.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<script>
3434
import { onMounted, ref, computed, onUnmounted, watch, watchEffect } from 'vue'
3535
import { iframeMonitoring } from '@opentiny/tiny-engine-common/js/monitor'
36-
import { useTranslate, useCanvas, useMaterial, useMessage, useResource } from '@opentiny/tiny-engine-meta-register'
36+
import { useTranslate, useCanvas, useMessage, useResource } from '@opentiny/tiny-engine-meta-register'
3737
import { NODE_UID, NODE_LOOP, DESIGN_MODE } from '../../common'
3838
import { registerHostkeyEvent, removeHostkeyEvent } from './keyboard'
3939
import CanvasMenu, { closeMenu, openMenu } from './components/CanvasMenu.vue'
@@ -117,7 +117,8 @@ export default {
117117
const beforeCanvasReady = () => {
118118
if (iframe.value) {
119119
const win = iframe.value.contentWindow
120-
win.thirdPartyDeps = useMaterial().materialState.thirdPartyDeps
120+
// 用于画布初始化组件依赖
121+
win.componentsDeps = useResource().appSchemaState.materialsDeps.scripts.filter((item) => item.components)
121122
122123
const { subscribe, unsubscribe } = useMessage()
123124
const { getSchemaDiff, patchLatestSchema, getSchema, getNode } = useCanvas()

packages/canvas/container/src/container.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,5 @@ export const initCanvas = ({ renderer, iframe, emit, controller }) => {
899899
}
900900

901901
setConfigure(useMaterial().getConfigureMap())
902-
canvasDispatch('updateDependencies', { detail: useMaterial().materialState.thirdPartyDeps })
903902
canvasState.loading = false
904903
}

packages/canvas/render/src/application-function/utils.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ref } from 'vue'
22
import TinyVue from '@opentiny/vue'
33
import * as TinyVueIcon from '@opentiny/vue-icon'
44
import { generateFunction } from '../data-utils'
5+
import { globalNotify } from '../canvas-function'
56

67
export interface IUtil {
78
name: string
@@ -18,7 +19,7 @@ export function useUtils(context: Record<string, any>) {
1819
const utils: Record<string, Function | any> = {}
1920
const getUtils = () => utils
2021

21-
const setUtils = (data: Array<IUtil>) => {
22+
const setUtils = async (data: Array<IUtil>) => {
2223
if (!Array.isArray(data)) {
2324
return
2425
}
@@ -52,6 +53,29 @@ export function useUtils(context: Record<string, any>) {
5253
utilsCollection[item.name] = generateFunction(item.content.value, context) || defaultFn
5354
}
5455
})
56+
57+
const npmUtilsImports = data
58+
.filter((item) => item.type === 'npm' && item.content.cdnLink)
59+
.map((item) => import(/* @vite-ignore */ item.content.cdnLink))
60+
const npmUtils = await Promise.allSettled(npmUtilsImports)
61+
62+
npmUtils.forEach((res, index) => {
63+
const { name, content } = data[index]
64+
const { exportName, destructuring, cdnLink } = content
65+
66+
if (res.status !== 'fulfilled') {
67+
globalNotify({
68+
type: 'error',
69+
message: `加载工具类“${name}”失败,请检查cdn链接是否正确,${cdnLink}`
70+
})
71+
72+
return
73+
}
74+
75+
const module = res.value
76+
utilsCollection[name] = destructuring ? module[exportName] : module.default
77+
})
78+
5579
Object.assign(utils, utilsCollection)
5680

5781
refreshKey.value++

packages/canvas/render/src/runner.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
import { createApp } from 'vue'
14-
import { addScript, addStyle, dynamicImportComponents, updateDependencies } from '../../common/index.js'
14+
import { addScript, addStyle, getComponents } from '../../common'
1515
import TinyI18nHost, { I18nInjectionKey } from '@opentiny/tiny-engine-common/js/i18n'
1616
import Main, { api } from './RenderMain'
1717
import lowcode from './lowcode'
@@ -31,8 +31,6 @@ const initRenderContext = () => {
3131

3232
window.TinyLowcodeComponent = {}
3333
window.TinyComponentLibs = {}
34-
35-
document.addEventListener('updateDependencies', updateDependencies)
3634
}
3735

3836
let App = null
@@ -83,10 +81,10 @@ export const createRender = (config) => {
8381
initRenderContext()
8482

8583
const { styles = [], scripts = [] } = config.canvasDependencies
86-
const { styles: thirdStyles = [], scripts: thirdScripts = [] } = window.thirdPartyDeps || {}
84+
const componentsDeps = window.componentsDeps || []
8785

8886
Promise.all([
89-
...thirdScripts.map(dynamicImportComponents),
90-
...scripts.map((src) => addScript(src)).concat([...thirdStyles, ...styles].map((src) => addStyle(src)))
87+
...componentsDeps.map(getComponents),
88+
...scripts.map((src) => addScript(src)).concat(styles.map((src) => addStyle(src)))
9189
]).finally(() => create(config))
9290
}

packages/canvas/render/type.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,10 @@ export declare global {
1010
TinyGlobalConfig: Record<string, any>
1111
loadBlockComponent: (blockName: string) => Promise<any>
1212
host: any
13+
componentsDeps: Array<{
14+
script: string
15+
package: string
16+
components: Record<string, string>
17+
}>
1318
}
1419
}

0 commit comments

Comments
 (0)