@sigmaott/base-next 1.4.39 → 1.4.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/plugins/wujie.ts +5 -96
- package/src/utils/micro.ts +8 -56
- package/src/utils/component-resolution.ts +0 -205
package/package.json
CHANGED
package/src/plugins/wujie.ts
CHANGED
|
@@ -1,110 +1,19 @@
|
|
|
1
|
-
// Type declarations for Wujie
|
|
2
|
-
declare global {
|
|
3
|
-
interface Window {
|
|
4
|
-
__POWERED_BY_WUJIE__?: boolean
|
|
5
|
-
__WUJIE_MOUNT?: () => void
|
|
6
|
-
__WUJIE_UNMOUNT?: () => void
|
|
7
|
-
__WUJIE?: {
|
|
8
|
-
mount: () => void
|
|
9
|
-
id?: string
|
|
10
|
-
cleanup?: () => void
|
|
11
|
-
}
|
|
12
|
-
$wujie?: {
|
|
13
|
-
bus?: {
|
|
14
|
-
$on: (event: string, callback: (data: any) => void) => void
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
parent?: {
|
|
18
|
-
__SIGMA_STATE__?: any
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
1
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
24
|
-
// Ensure nuxtApp is properly initialized
|
|
25
|
-
if (!nuxtApp) {
|
|
26
|
-
console.warn('[Wujie] nuxtApp is not available')
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
2
|
nuxtApp.hook('app:created', async (app) => {
|
|
31
|
-
await new Promise<void>((resolve
|
|
3
|
+
await new Promise<void>((resolve) => {
|
|
32
4
|
if (window.__POWERED_BY_WUJIE__) {
|
|
33
5
|
window.__WUJIE_MOUNT = () => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (typeof window !== 'undefined' && window.parent && window.parent.__SIGMA_STATE__) {
|
|
37
|
-
console.log('[Wujie] Syncing micro state')
|
|
38
|
-
}
|
|
39
|
-
resolve()
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.error('[Wujie] Error during mount:', error)
|
|
42
|
-
reject(error)
|
|
43
|
-
}
|
|
6
|
+
syncMicroState()
|
|
7
|
+
resolve()
|
|
44
8
|
}
|
|
45
9
|
window.__WUJIE_UNMOUNT = () => {
|
|
46
|
-
|
|
47
|
-
if (app && typeof app.unmount === 'function') {
|
|
48
|
-
app.unmount()
|
|
49
|
-
}
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.error('[Wujie] Error during unmount:', error)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Add timeout to prevent hanging
|
|
56
|
-
const timeout = setTimeout(() => {
|
|
57
|
-
console.warn('[Wujie] Mount timeout, resolving anyway')
|
|
58
|
-
resolve()
|
|
59
|
-
}, 5000)
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
if (window.__WUJIE && typeof window.__WUJIE.mount === 'function') {
|
|
63
|
-
window.__WUJIE.mount()
|
|
64
|
-
clearTimeout(timeout)
|
|
65
|
-
} else {
|
|
66
|
-
console.warn('[Wujie] __WUJIE.mount is not available')
|
|
67
|
-
clearTimeout(timeout)
|
|
68
|
-
resolve()
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
clearTimeout(timeout)
|
|
72
|
-
console.error('[Wujie] Error mounting app:', error)
|
|
73
|
-
reject(error)
|
|
10
|
+
app.unmount()
|
|
74
11
|
}
|
|
12
|
+
window.__WUJIE.mount()
|
|
75
13
|
}
|
|
76
14
|
else {
|
|
77
15
|
resolve()
|
|
78
16
|
}
|
|
79
17
|
})
|
|
80
18
|
})
|
|
81
|
-
|
|
82
|
-
// Enhanced error handling for component resolution
|
|
83
|
-
nuxtApp.hook('app:error', (error) => {
|
|
84
|
-
if (error?.message?.includes('Couldn\'t resolve component')) {
|
|
85
|
-
console.warn('[Nuxt] Component resolution error detected:', error)
|
|
86
|
-
// Simple recovery - reload page after delay
|
|
87
|
-
setTimeout(() => {
|
|
88
|
-
if (typeof window !== 'undefined' && window.location) {
|
|
89
|
-
window.location.reload()
|
|
90
|
-
}
|
|
91
|
-
}, 1000)
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
// Handle Vue component errors - with safety check
|
|
96
|
-
if (nuxtApp.vueApp && nuxtApp.vueApp.config) {
|
|
97
|
-
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
|
|
98
|
-
if (error?.message?.includes('Couldn\'t resolve component')) {
|
|
99
|
-
console.warn('[Vue] Component resolution error:', error)
|
|
100
|
-
setTimeout(() => {
|
|
101
|
-
if (typeof window !== 'undefined' && window.location) {
|
|
102
|
-
window.location.reload()
|
|
103
|
-
}
|
|
104
|
-
}, 1000)
|
|
105
|
-
} else {
|
|
106
|
-
console.error('[Vue] Error:', error, 'Info:', info)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
19
|
})
|
package/src/utils/micro.ts
CHANGED
|
@@ -74,64 +74,16 @@ const defaultLifecycles: Lifecycles = {
|
|
|
74
74
|
beforeLoad: (appWindow) => {
|
|
75
75
|
console.log(`${appWindow.__WUJIE.id} beforeLoad`)
|
|
76
76
|
console.log('[LOG] ~ file: micro.ts:76 ~ appWindow:', appWindow)
|
|
77
|
-
|
|
78
|
-
addMicroApp(appWindow)
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.error(`[Micro] Error adding micro app ${appWindow.__WUJIE.id}:`, error)
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
beforeMount: (appWindow) => {
|
|
84
|
-
console.log(`${appWindow.__WUJIE.id} beforeMount`)
|
|
85
|
-
// Ensure component resolution is ready
|
|
86
|
-
return new Promise((resolve) => {
|
|
87
|
-
setTimeout(() => {
|
|
88
|
-
resolve()
|
|
89
|
-
}, 100)
|
|
90
|
-
})
|
|
91
|
-
},
|
|
92
|
-
afterMount: (appWindow) => {
|
|
93
|
-
console.log(`${appWindow.__WUJIE.id} afterMount`)
|
|
94
|
-
// Verify component is properly mounted
|
|
95
|
-
try {
|
|
96
|
-
if (appWindow.document && appWindow.document.querySelector('[data-v-app]')) {
|
|
97
|
-
console.log(`${appWindow.__WUJIE.id} component properly mounted`)
|
|
98
|
-
}
|
|
99
|
-
} catch (error) {
|
|
100
|
-
console.warn(`${appWindow.__WUJIE.id} component mount verification failed:`, error)
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
beforeUnmount: (appWindow) => {
|
|
104
|
-
console.log(`${appWindow.__WUJIE.id} beforeUnmount`)
|
|
105
|
-
try {
|
|
106
|
-
// Clean up any pending operations
|
|
107
|
-
if (appWindow.__WUJIE?.cleanup) {
|
|
108
|
-
appWindow.__WUJIE.cleanup()
|
|
109
|
-
}
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error(`${appWindow.__WUJIE.id} cleanup error:`, error)
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
afterUnmount: (appWindow) => console.log(`${appWindow.__WUJIE.id} afterUnmount`),
|
|
115
|
-
activated: (appWindow) => {
|
|
116
|
-
console.log(`${appWindow.__WUJIE.id} activated`)
|
|
117
|
-
// Ensure component is ready when activated
|
|
118
|
-
return new Promise((resolve) => {
|
|
119
|
-
setTimeout(() => {
|
|
120
|
-
resolve()
|
|
121
|
-
}, 50)
|
|
122
|
-
})
|
|
77
|
+
addMicroApp(appWindow)
|
|
123
78
|
},
|
|
79
|
+
beforeMount: appWindow => console.log(`${appWindow.__WUJIE.id} beforeMount`),
|
|
80
|
+
afterMount: appWindow => console.log(`${appWindow.__WUJIE.id} afterMount`),
|
|
81
|
+
beforeUnmount: appWindow => console.log(`${appWindow.__WUJIE.id} beforeUnmount `),
|
|
82
|
+
afterUnmount: appWindow => console.log(`${appWindow.__WUJIE.id} afterUnmount`),
|
|
83
|
+
activated: appWindow => console.log(`${appWindow.__WUJIE.id} activated`),
|
|
124
84
|
deactivated: appWindow => console.log(`${appWindow.__WUJIE.id} deactivated`),
|
|
125
|
-
loadError: (url, e) => {
|
|
126
|
-
|
|
127
|
-
// Attempt recovery for component resolution errors
|
|
128
|
-
if (e.message?.includes('Couldn\'t resolve component')) {
|
|
129
|
-
console.warn('[Micro] Component resolution error detected, attempting recovery...')
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
window.location.reload()
|
|
132
|
-
}, 2000)
|
|
133
|
-
}
|
|
134
|
-
},
|
|
85
|
+
loadError: (url, e) => console.log(`${url}`, e),
|
|
86
|
+
|
|
135
87
|
}
|
|
136
88
|
|
|
137
89
|
const plugins: Array<plugin> = [
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions for handling component resolution issues in micro-frontend architecture
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface ComponentResolutionError extends Error {
|
|
6
|
-
componentName?: string
|
|
7
|
-
path?: string
|
|
8
|
-
isRecoverable?: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Detects if an error is related to component resolution
|
|
13
|
-
*/
|
|
14
|
-
export function isComponentResolutionError(error: any): error is ComponentResolutionError {
|
|
15
|
-
return error?.message?.includes('Couldn\'t resolve component') ||
|
|
16
|
-
error?.message?.includes('Failed to resolve component') ||
|
|
17
|
-
error?.message?.includes('Component not found')
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Handles component resolution errors with recovery strategies
|
|
22
|
-
*/
|
|
23
|
-
export function handleComponentResolutionError(error: ComponentResolutionError, context: string = 'unknown') {
|
|
24
|
-
try {
|
|
25
|
-
console.warn(`[${context}] Component resolution error detected:`, error)
|
|
26
|
-
|
|
27
|
-
// Ensure error has message property
|
|
28
|
-
if (!error || typeof error !== 'object') {
|
|
29
|
-
console.error(`[${context}] Invalid error object:`, error)
|
|
30
|
-
return false
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Extract component name and path from error message
|
|
34
|
-
const componentMatch = error.message?.match(/component "([^"]+)"/)
|
|
35
|
-
const pathMatch = error.message?.match(/at "([^"]+)"/)
|
|
36
|
-
|
|
37
|
-
if (componentMatch) {
|
|
38
|
-
error.componentName = componentMatch[1]
|
|
39
|
-
}
|
|
40
|
-
if (pathMatch) {
|
|
41
|
-
error.path = pathMatch[1]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Determine if error is recoverable
|
|
45
|
-
error.isRecoverable = !error.message?.includes('permanent') &&
|
|
46
|
-
!error.message?.includes('fatal')
|
|
47
|
-
|
|
48
|
-
if (error.isRecoverable) {
|
|
49
|
-
console.log(`[${context}] Attempting recovery for component: ${error.componentName} at ${error.path}`)
|
|
50
|
-
|
|
51
|
-
// Strategy 1: Wait and retry - with safety check
|
|
52
|
-
setTimeout(() => {
|
|
53
|
-
try {
|
|
54
|
-
if (typeof window !== 'undefined' && window.location) {
|
|
55
|
-
console.log(`[${context}] Reloading page for recovery...`)
|
|
56
|
-
window.location.reload()
|
|
57
|
-
}
|
|
58
|
-
} catch (reloadError) {
|
|
59
|
-
console.error(`[${context}] Error during page reload:`, reloadError)
|
|
60
|
-
}
|
|
61
|
-
}, 1000)
|
|
62
|
-
} else {
|
|
63
|
-
console.error(`[${context}] Non-recoverable component resolution error:`, error)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return error.isRecoverable
|
|
67
|
-
} catch (handlerError) {
|
|
68
|
-
console.error(`[${context}] Error in handleComponentResolutionError:`, handlerError)
|
|
69
|
-
return false
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Creates a retry mechanism for component resolution
|
|
75
|
-
*/
|
|
76
|
-
export function createComponentResolutionRetry(
|
|
77
|
-
maxRetries: number = 3,
|
|
78
|
-
delay: number = 1000
|
|
79
|
-
) {
|
|
80
|
-
let retryCount = 0
|
|
81
|
-
|
|
82
|
-
return function retryComponentResolution<T>(
|
|
83
|
-
operation: () => T | Promise<T>,
|
|
84
|
-
context: string = 'component-resolution'
|
|
85
|
-
): Promise<T> {
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
const attempt = async () => {
|
|
88
|
-
try {
|
|
89
|
-
const result = await operation()
|
|
90
|
-
resolve(result)
|
|
91
|
-
} catch (error) {
|
|
92
|
-
if (isComponentResolutionError(error) && retryCount < maxRetries) {
|
|
93
|
-
retryCount++
|
|
94
|
-
console.warn(`[${context}] Retry ${retryCount}/${maxRetries} for component resolution...`)
|
|
95
|
-
|
|
96
|
-
setTimeout(() => {
|
|
97
|
-
attempt()
|
|
98
|
-
}, delay * retryCount)
|
|
99
|
-
} else {
|
|
100
|
-
handleComponentResolutionError(error as ComponentResolutionError, context)
|
|
101
|
-
reject(error)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
attempt()
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Debounced component resolution checker
|
|
113
|
-
*/
|
|
114
|
-
export function createComponentResolutionChecker(
|
|
115
|
-
checkInterval: number = 100,
|
|
116
|
-
maxChecks: number = 50
|
|
117
|
-
) {
|
|
118
|
-
let checkCount = 0
|
|
119
|
-
|
|
120
|
-
return function checkComponentResolution(
|
|
121
|
-
componentName: string,
|
|
122
|
-
context: string = 'component-checker'
|
|
123
|
-
): Promise<boolean> {
|
|
124
|
-
return new Promise((resolve) => {
|
|
125
|
-
const check = () => {
|
|
126
|
-
checkCount++
|
|
127
|
-
|
|
128
|
-
// Check if component exists in DOM
|
|
129
|
-
const componentExists = document.querySelector(`[data-component="${componentName}"]`) ||
|
|
130
|
-
document.querySelector(`[data-v-${componentName}]`) ||
|
|
131
|
-
document.querySelector(`#${componentName}`)
|
|
132
|
-
|
|
133
|
-
if (componentExists) {
|
|
134
|
-
console.log(`[${context}] Component ${componentName} found after ${checkCount} checks`)
|
|
135
|
-
resolve(true)
|
|
136
|
-
} else if (checkCount >= maxChecks) {
|
|
137
|
-
console.warn(`[${context}] Component ${componentName} not found after ${maxChecks} checks`)
|
|
138
|
-
resolve(false)
|
|
139
|
-
} else {
|
|
140
|
-
setTimeout(check, checkInterval)
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
check()
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Global error handler for component resolution issues
|
|
151
|
-
*/
|
|
152
|
-
export function setupGlobalComponentResolutionHandler() {
|
|
153
|
-
// Ensure we're in a browser environment
|
|
154
|
-
if (typeof window === 'undefined') {
|
|
155
|
-
return
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Handle unhandled promise rejections
|
|
159
|
-
window.addEventListener('unhandledrejection', (event) => {
|
|
160
|
-
try {
|
|
161
|
-
if (isComponentResolutionError(event.reason)) {
|
|
162
|
-
console.warn('[Global] Unhandled component resolution error:', event.reason)
|
|
163
|
-
handleComponentResolutionError(event.reason, 'global-unhandled')
|
|
164
|
-
event.preventDefault()
|
|
165
|
-
}
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error('[Global] Error in unhandledrejection handler:', error)
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
// Handle general errors
|
|
172
|
-
window.addEventListener('error', (event) => {
|
|
173
|
-
try {
|
|
174
|
-
if (isComponentResolutionError(event.error)) {
|
|
175
|
-
console.warn('[Global] Component resolution error:', event.error)
|
|
176
|
-
handleComponentResolutionError(event.error, 'global-error')
|
|
177
|
-
event.preventDefault()
|
|
178
|
-
}
|
|
179
|
-
} catch (error) {
|
|
180
|
-
console.error('[Global] Error in error handler:', error)
|
|
181
|
-
}
|
|
182
|
-
})
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Vue composable for component resolution error handling
|
|
187
|
-
*/
|
|
188
|
-
export function useComponentResolutionError() {
|
|
189
|
-
const errorHandler = (error: any, context: string = 'vue-component') => {
|
|
190
|
-
if (isComponentResolutionError(error)) {
|
|
191
|
-
return handleComponentResolutionError(error, context)
|
|
192
|
-
}
|
|
193
|
-
return false
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const retryHandler = createComponentResolutionRetry()
|
|
197
|
-
const checker = createComponentResolutionChecker()
|
|
198
|
-
|
|
199
|
-
return {
|
|
200
|
-
errorHandler,
|
|
201
|
-
retryHandler,
|
|
202
|
-
checker,
|
|
203
|
-
isComponentResolutionError
|
|
204
|
-
}
|
|
205
|
-
}
|