feat(renderer): 悦码渲染器增加 sentry 做异常监听

This commit is contained in:
wangxuefeng
2025-03-20 20:09:49 +08:00
parent 22145b3893
commit 64b59a06a3
10 changed files with 408 additions and 1 deletions

View 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": ""
}
}

View 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>

View File

@@ -0,0 +1 @@
export { default } from './adapter.vue';

View 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"]
}

View 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,
}),
],
});