feat(renderer): 悦码渲染器增加 sentry 做异常监听
This commit is contained in:
		
							parent
							
								
									22145b3893
								
							
						
					
					
						commit
						64b59a06a3
					
				
							
								
								
									
										2
									
								
								.npmrc
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								.npmrc
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| registry = "https://registry.npmmirror.com" | registry = https://registry.npmmirror.com | ||||||
| @sy:registry=http://sy-registry.shiyue.com | @sy:registry=http://sy-registry.shiyue.com | ||||||
| public-hoist-pattern[]=husky | public-hoist-pattern[]=husky | ||||||
| public-hoist-pattern[]=eslint | public-hoist-pattern[]=eslint | ||||||
|  | |||||||
							
								
								
									
										125
									
								
								apps/docs/src/guide/integration/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								apps/docs/src/guide/integration/index.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,125 @@ | |||||||
|  | # 低代码渲染器接入指南 | ||||||
|  | 
 | ||||||
|  | ## 1. 概述 | ||||||
|  | 
 | ||||||
|  | - 1.1 什么是低代码渲染器 | ||||||
|  | - 1.2 核心功能和优势 | ||||||
|  | - 1.3 适用项目 | ||||||
|  |   - vue2 | ||||||
|  |   - vue3 | ||||||
|  |   - react | ||||||
|  |   - 其他框架请联系伊利(sy)或王雪峰(sy3570)添加适配器 | ||||||
|  | 
 | ||||||
|  | ## 2. 环境要求 | ||||||
|  | 
 | ||||||
|  | - node >= 20 | ||||||
|  | - vue2 > 2.7.0 | ||||||
|  | - vue3 > 3.5.0 | ||||||
|  | - react > 18.0.0 | ||||||
|  | 
 | ||||||
|  | ## 3. 准备工作 | ||||||
|  | 
 | ||||||
|  | 1.npmrc 配置文件增加镜像指定,sy 组件库走 shiyue 源,其他走淘宝镜像 | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | registry=https://registry.npmmirror.com | ||||||
|  | @sy:registry=http://sy-registry.shiyue.com | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 2. node 至少要升级为 20 以上的版本 | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | nvm install 20 | ||||||
|  | nvm use 20 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 若不可行,请查看 node 官网历代大版本的 lts 版本(长期维护),自行安装,查看是否能正常渲染,选取稳定渲染悦码的那一个 node 版本作为开发环境 | ||||||
|  | 
 | ||||||
|  | ## 5. 接入方式 | ||||||
|  | 
 | ||||||
|  | ### vue2 项目接入 | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | pnpm i @sy/wujie-vue2-renderer-adapter@latest --save | ||||||
|  | # or 或者 | ||||||
|  | npm i @sy/wujie-vue2-renderer-adapter@latest --save | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### vue3 项目接入 | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | pnpm i @sy/wujie-vue3-renderer-adapter@latest --save | ||||||
|  | # or 或者 | ||||||
|  | npm i @sy/wujie-vue3-renderer-adapter@latest --save | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### react 项目接入 | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | pnpm i @sy/wujie-react-renderer-adapter@latest --save | ||||||
|  | # or 或者 | ||||||
|  | npm i @sy/wujie-react-renderer-adapter@latest --save | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## API 参考 | ||||||
|  | 
 | ||||||
|  | - 6.1 Props 参数详解 | ||||||
|  | - 6.2 事件监听与回调 | ||||||
|  | - 6.3 实例方法 | ||||||
|  | - 6.4 拦截器使用 | ||||||
|  | 
 | ||||||
|  | ## 7. 高级用法 | ||||||
|  | 
 | ||||||
|  | - 7.1 自定义主题 | ||||||
|  | - 7.2 数据交互与通信 | ||||||
|  | - 7.3 插件扩展 | ||||||
|  | - 7.4 微前端降级处理 | ||||||
|  | 
 | ||||||
|  | ## 8. 故障排除 | ||||||
|  | 
 | ||||||
|  | - 8.1 常见错误及解决方案 | ||||||
|  | - 8.2 日志与调试 | ||||||
|  |   - 悦码的日志输出一般在控制台中有 `console.ts 40` 的源码位置标记 | ||||||
|  | - 8.3 兼容性问题处理 | ||||||
|  | - renderer-adapter 是默认使用无界降级的 iframe 加载悦码渲染器应用的,你如果希望悦码与你的页面有更深的上下文结合和交互,你可以手动设置 `degrade` 为 `false`,这将开启高级渲染,但有一定的兼容性问题,如果需要在 C 端运行业务,我建议你采用默认的渲染模式 | ||||||
|  | 
 | ||||||
|  | ```vue | ||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue'; | ||||||
|  | import { WujieVue3RendererAdapter } from '@sy/wujie-vue3-renderer-adapter'; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <!-- 高级渲染模式,与原页面深度共享 document 与内存上下文 --> | ||||||
|  |   <WujieVue3RendererAdapter | ||||||
|  |     :degrade="false" | ||||||
|  |     fileId="test123" | ||||||
|  |     projectId="test123" | ||||||
|  |   /> | ||||||
|  |   <!-- 默认降级渲染模式,使用无界 iframe 加载悦码渲染器应用 --> | ||||||
|  |   <!-- 缺点在于弹窗与遮罩层会约束在 iframe 空间内,无法与原页面共享 document,但无界的 iframe 可以与原页面共享内存上下文 ,这是比传统 iframe 更优的解决方案 --> | ||||||
|  |   <WujieVue3RendererAdapter fileId="test123" projectId="test123" /> | ||||||
|  | </template> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - 8.4 性能问题诊断 | ||||||
|  | - 悦码渲染器内部使用了 sentry 上报错误,你可以跟 徐川(sy0182) 申请对应警告邮箱的使用权,获取报错邮件 | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## 9. 最佳实践 | ||||||
|  | 
 | ||||||
|  | - 9.1 推荐的项目结构 | ||||||
|  | - 9.2 安全性建议 | ||||||
|  | - 9.3 性能优化建议 | ||||||
|  | - 9.4 版本升级策略 | ||||||
|  | 
 | ||||||
|  | ## 10. 示例 | ||||||
|  | 
 | ||||||
|  |     - 10.1 基础示例 | ||||||
|  |     - 10.2 完整应用示例 | ||||||
|  |     - 10.3 实际案例展示 | ||||||
|  | 
 | ||||||
|  | ## 11. 常见问题 (FAQ) | ||||||
|  | 
 | ||||||
|  | ## 12. 联系支持与反馈渠道 | ||||||
| @ -17,6 +17,15 @@ const app = createApp(App); | |||||||
| Sentry.init({ | Sentry.init({ | ||||||
|   app, |   app, | ||||||
|   dsn: 'https://5bcf1344794fea64fc5e5fe7da4821c1@o4508962650783744.ingest.de.sentry.io/4508962653143120', |   dsn: 'https://5bcf1344794fea64fc5e5fe7da4821c1@o4508962650783744.ingest.de.sentry.io/4508962653143120', | ||||||
|  |   integrations: [ | ||||||
|  |     // 异常路径回放
 | ||||||
|  |     Sentry.replayIntegration(), | ||||||
|  |     // 异常端信息追踪
 | ||||||
|  |     Sentry.browserTracingIntegration(), | ||||||
|  |   ], | ||||||
|  |   // Session Replay
 | ||||||
|  |   replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
 | ||||||
|  |   replaysOnErrorSampleRate: 1, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
 | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| // 批量注册组件
 | // 批量注册组件
 | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								apps/renderer/src/utils/alert.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								apps/renderer/src/utils/alert.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | export function test() { | ||||||
|  |   console.log('test'); | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								apps/renderer/src/utils/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								apps/renderer/src/utils/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | export * from './alert'; | ||||||
							
								
								
									
										39
									
								
								packages/renderer-adapter/wujie-vue2/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								packages/renderer-adapter/wujie-vue2/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | { | ||||||
|  |   "name": "@sy/wujie-vue3-renderer-adapter", | ||||||
|  |   "version": "1.0.0-alpha.2", | ||||||
|  |   "description": "wujie-vue3 ycode renderer adapter", | ||||||
|  |   "type": "module", | ||||||
|  |   "scripts": { | ||||||
|  |     "build": "vite build" | ||||||
|  |   }, | ||||||
|  |   "alias": { | ||||||
|  |     "#": "./src" | ||||||
|  |   }, | ||||||
|  |   "files": [ | ||||||
|  |     "dist" | ||||||
|  |   ], | ||||||
|  |   "main": "./dist/index.cjs", | ||||||
|  |   "module": "./dist/index.js", | ||||||
|  |   "unpkg": "./dist/index.js", | ||||||
|  |   "types": "./dist/index.d.ts", | ||||||
|  |   "exports": { | ||||||
|  |     ".": { | ||||||
|  |       "types": "./dist/types/index.d.ts", | ||||||
|  |       "import": "./dist/index.mjs", | ||||||
|  |       "require": "./dist/index.cjs", | ||||||
|  |       "default": "./dist/index.mjs" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "licia-es": "catalog:", | ||||||
|  |     "vue": "2.7.16", | ||||||
|  |     "wujie-vue2": "1.0.22" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "@types/axios": "0.14.4", | ||||||
|  |     "@vitejs/plugin-vue": "catalog:", | ||||||
|  |     "axios": "catalog:", | ||||||
|  |     "vite-plugin-dts": "catalog:", | ||||||
|  |     "vue-router": "" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										132
									
								
								packages/renderer-adapter/wujie-vue2/src/adapter.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								packages/renderer-adapter/wujie-vue2/src/adapter.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,132 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import type { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; | ||||||
|  | 
 | ||||||
|  | import type { Router, RouteRecordRaw } from 'vue-router'; | ||||||
|  | 
 | ||||||
|  | import { onBeforeUnmount, onMounted } from 'vue'; | ||||||
|  | 
 | ||||||
|  | import WujieVue from 'wujie-vue3'; | ||||||
|  | 
 | ||||||
|  | // @ts-ignore ignore the type error | ||||||
|  | import { version } from '/package.json'; | ||||||
|  | 
 | ||||||
|  | // 定义拦截器类型 | ||||||
|  | interface AxiosInterceptors { | ||||||
|  |   request?: { | ||||||
|  |     onFulfilled?: ( | ||||||
|  |       config: InternalAxiosRequestConfig, | ||||||
|  |     ) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>; | ||||||
|  |     onRejected?: (error: any) => any; | ||||||
|  |   }; | ||||||
|  |   response?: { | ||||||
|  |     onFulfilled?: ( | ||||||
|  |       response: AxiosResponse, | ||||||
|  |     ) => AxiosResponse | Promise<AxiosResponse>; | ||||||
|  |     onRejected?: (error: any) => any; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const props = withDefaults( | ||||||
|  |   defineProps<{ | ||||||
|  |     [key: string]: any; | ||||||
|  |     applicationId: number; | ||||||
|  |     degrade?: boolean; | ||||||
|  |     fileId: number | string; | ||||||
|  |     interceptors?: AxiosInterceptors; | ||||||
|  |     name?: string; | ||||||
|  |     // 传递给子应用的参数 payload | ||||||
|  |     payload?: Record<string, any>; | ||||||
|  |     projectId: number; | ||||||
|  |     route?: RouteRecordRaw; | ||||||
|  |     router?: Router; | ||||||
|  |     sync?: boolean; | ||||||
|  |     url?: string; | ||||||
|  |   }>(), | ||||||
|  |   { | ||||||
|  |     // 默认 wujie 降级,能避免很多兼容问题 | ||||||
|  |     degrade: true, | ||||||
|  |     // 默认不使用拦截器 | ||||||
|  |     interceptors: () => ({}), | ||||||
|  |     // 默认不使用 name | ||||||
|  |     name: undefined, | ||||||
|  |     // 默认不使用 payload | ||||||
|  |     payload: () => ({}), | ||||||
|  |     // 默认不使用 route | ||||||
|  |     route: undefined, | ||||||
|  |     // 默认不使用 router | ||||||
|  |     router: undefined, | ||||||
|  |     sync: true, | ||||||
|  |     url: 'https://y-code-renderer.shiyue.com', | ||||||
|  |   }, | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | const { bus } = WujieVue; | ||||||
|  | 
 | ||||||
|  | // 生命周期钩子 | ||||||
|  | const beforeLoad = (appWindow: Window) => { | ||||||
|  |   console.log(`${props.name} 开始加载`, appWindow); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const afterMount = (appWindow: Window) => { | ||||||
|  |   console.log(`${props.name} 加载完成`, appWindow); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 事件处理 | ||||||
|  | const handleMessage = (data: any) => { | ||||||
|  |   console.log(`${props.name} 收到子应用消息:`, data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 准备传递给子应用的数据 | ||||||
|  | const subAppProps = { | ||||||
|  |   ...props, | ||||||
|  |   adapterInfo: { | ||||||
|  |     version, | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 监听子应用的事件 | ||||||
|  | const handleReady = (data: any) => { | ||||||
|  |   console.log(`${props.name} 子应用就绪:`, data); | ||||||
|  |   // 可以在这里执行一些操作 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const handleRenderSuccess = () => { | ||||||
|  |   console.log(`${props.name} 子应用渲染成功`); | ||||||
|  |   // 通知父应用 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const handleRenderFail = (error: any) => { | ||||||
|  |   console.error(`${props.name} 子应用渲染失败:`, error); | ||||||
|  |   // 处理错误情况 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | onMounted(() => { | ||||||
|  |   // 注册事件监听 | ||||||
|  |   bus.$on('message', handleMessage); | ||||||
|  |   bus.$on('ready', handleReady); | ||||||
|  |   bus.$on('render-success', handleRenderSuccess); | ||||||
|  |   bus.$on('render-fail', handleRenderFail); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | onBeforeUnmount(() => { | ||||||
|  |   // 移除所有事件监听 | ||||||
|  |   bus.$off('message', handleMessage); | ||||||
|  |   bus.$off('ready', handleReady); | ||||||
|  |   bus.$off('render-success', handleRenderSuccess); | ||||||
|  |   bus.$off('render-fail', handleRenderFail); | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <WujieVue | ||||||
|  |     :name="name || fileId" | ||||||
|  |     :url="url" | ||||||
|  |     :sync="sync" | ||||||
|  |     width="100%" | ||||||
|  |     height="100%" | ||||||
|  |     :degrade="degrade" | ||||||
|  |     :props="subAppProps" | ||||||
|  |     :before-load="beforeLoad" | ||||||
|  |     :after-mount="afterMount" | ||||||
|  |   /> | ||||||
|  | </template> | ||||||
							
								
								
									
										1
									
								
								packages/renderer-adapter/wujie-vue2/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/renderer-adapter/wujie-vue2/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | export { default } from './adapter.vue'; | ||||||
							
								
								
									
										29
									
								
								packages/renderer-adapter/wujie-vue2/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								packages/renderer-adapter/wujie-vue2/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     "target": "ESNext", | ||||||
|  |     "jsx": "preserve", | ||||||
|  |     "jsxFactory": "h", | ||||||
|  |     "jsxFragmentFactory": "Fragment", | ||||||
|  |     "lib": ["ESNext", "DOM", "DOM.Iterable"], | ||||||
|  |     "baseUrl": ".", | ||||||
|  |     "module": "ESNext", | ||||||
|  |     "moduleResolution": "Node", | ||||||
|  |     "paths": { | ||||||
|  |       "@/*": ["src/*"] | ||||||
|  |     }, | ||||||
|  |     "resolveJsonModule": true, | ||||||
|  |     "types": ["vite/client", "vue/runtime-dom"], | ||||||
|  |     "strict": true, | ||||||
|  |     "useUnknownInCatchVariables": false, | ||||||
|  |     "declaration": true, | ||||||
|  |     "declarationDir": "dist/types", | ||||||
|  |     "outDir": "dist", | ||||||
|  |     "sourceMap": true, | ||||||
|  |     "allowSyntheticDefaultImports": true, | ||||||
|  |     "esModuleInterop": true, | ||||||
|  |     "forceConsistentCasingInFileNames": true, | ||||||
|  |     "skipLibCheck": true | ||||||
|  |   }, | ||||||
|  |   "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], | ||||||
|  |   "exclude": ["node_modules", "dist"] | ||||||
|  | } | ||||||
							
								
								
									
										68
									
								
								packages/renderer-adapter/wujie-vue2/vite.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								packages/renderer-adapter/wujie-vue2/vite.config.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | |||||||
|  | import path from 'node:path'; | ||||||
|  | import { fileURLToPath } from 'node:url'; | ||||||
|  | 
 | ||||||
|  | import vue from '@vitejs/plugin-vue'; | ||||||
|  | import { defineConfig } from 'vite'; | ||||||
|  | import dts from 'vite-plugin-dts'; | ||||||
|  | 
 | ||||||
|  | const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||||||
|  | 
 | ||||||
|  | export default defineConfig({ | ||||||
|  |   build: { | ||||||
|  |     cssCodeSplit: true, | ||||||
|  |     lib: { | ||||||
|  |       entry: path.resolve(__dirname, 'src/index.ts'), | ||||||
|  |       fileName: (format) => { | ||||||
|  |         switch (format) { | ||||||
|  |           case 'cjs': { | ||||||
|  |             return 'index.cjs'; | ||||||
|  |           } | ||||||
|  |           case 'es': { | ||||||
|  |             return 'index.mjs'; | ||||||
|  |           } | ||||||
|  |           case 'umd': { | ||||||
|  |             return 'index.js'; | ||||||
|  |           } | ||||||
|  |           default: { | ||||||
|  |             return `index.${format}.js`; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       formats: ['es', 'cjs', 'umd'], | ||||||
|  |       name: 'RendererAdapter', | ||||||
|  |     }, | ||||||
|  |     outDir: 'dist', | ||||||
|  |     rollupOptions: { | ||||||
|  |       external: ['vue'], | ||||||
|  |       output: { | ||||||
|  |         assetFileNames: (assetInfo) => { | ||||||
|  |           if (assetInfo.name === 'style.css') return 'assets/[name][extname]'; | ||||||
|  |           return 'assets/[name]-[hash][extname]'; | ||||||
|  |         }, | ||||||
|  |         globals: { | ||||||
|  |           vue: 'Vue', | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     sourcemap: true, | ||||||
|  |   }, | ||||||
|  |   css: { | ||||||
|  |     extract: false, | ||||||
|  |     modules: { | ||||||
|  |       localsConvention: 'camelCaseOnly', | ||||||
|  |       scopeBehaviour: 'local', | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   plugins: [ | ||||||
|  |     vue({ | ||||||
|  |       css: { | ||||||
|  |         injectCss: true, | ||||||
|  |       }, | ||||||
|  |     }), | ||||||
|  |     dts({ | ||||||
|  |       insertTypesEntry: true, | ||||||
|  |       outDir: 'dist/types', | ||||||
|  |       staticImport: true, | ||||||
|  |     }), | ||||||
|  |   ], | ||||||
|  | }); | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 wangxuefeng
						wangxuefeng