-
Notifications
You must be signed in to change notification settings - Fork 20
增加支持客户端的eventCenter代理类,解决从@tarojs/taro导入的eventCenter为空的问题 #47
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for a client-side eventCenter proxy class to resolve the issue of eventCenter being null when imported from @tarojs/taro. The solution implements a lazy-loading proxy that defers loading the actual eventCenter from @tarojs/runtime until needed, providing compatibility for SSR environments.
Key changes:
- Adds a new EventCenterProxy class that implements lazy loading of @tarojs/runtime's eventCenter
- Exports eventCenter from the main Taro API module to make it available to consumers
- Implements a queuing mechanism for method calls made before the actual eventCenter is loaded
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
File | Description |
---|---|
packages/nextjs/taro/src/index.ts | Adds eventCenter import and export to make it available in the main Taro API |
packages/nextjs/taro/src/basics/index.ts | Exports the eventCenter module from the basics package |
packages/nextjs/taro/src/basics/eventCenter.ts | Implements the EventCenterProxy class with lazy loading and method queuing |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
} | ||
|
||
// 创建代理方法 | ||
createProxyMethod(method) { |
Copilot
AI
Sep 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter 'method' should have a type annotation. Consider adding ': string' to specify the expected parameter type.
createProxyMethod(method) { | |
createProxyMethod(method: string) { |
Copilot uses AI. Check for mistakes.
const loadEventCenter = promisify( | ||
limited.async('loadEventCenter', this.loadEventCenter) | ||
) | ||
loadEventCenter() // 触发加载 |
Copilot
AI
Sep 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loadEventCenter promise is created but not awaited or handled. This could lead to unhandled promise rejections if the loading fails. Consider using 'loadEventCenter().catch(() => {})' or properly handling the promise.
loadEventCenter() // 触发加载 | |
loadEventCenter().catch(() => {}) // 触发加载,避免未处理的promise拒绝 |
Copilot uses AI. Check for mistakes.
interface EventCenterProxy { | ||
ready: boolean | ||
eventCenter: any | ||
pendingCalls: any[] |
Copilot
AI
Sep 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interface uses 'any' types which reduces type safety. Consider defining more specific types for 'eventCenter' and 'pendingCalls' to improve code maintainability and catch potential runtime errors.
interface EventCenterProxy { | |
ready: boolean | |
eventCenter: any | |
pendingCalls: any[] | |
interface EventCenterMethods { | |
on: (...args: any[]) => any | |
off: (...args: any[]) => any | |
trigger: (...args: any[]) => any | |
once: (...args: any[]) => any | |
} | |
interface PendingCall { | |
method: keyof EventCenterMethods | |
args: any[] | |
resolve: (value: any) => void | |
reject: (reason?: any) => void | |
} | |
interface EventCenterProxy { | |
ready: boolean | |
eventCenter: EventCenterMethods | null | |
pendingCalls: PendingCall[] |
Copilot uses AI. Check for mistakes.
} | ||
|
||
// 加载真实eventCenter | ||
async loadEventCenter() { |
Copilot
AI
Sep 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loadEventCenter method lacks protection against concurrent calls. If multiple methods are called simultaneously before the eventCenter is loaded, this could result in multiple import attempts. Consider adding a loading flag or using a singleton promise to prevent race conditions.
Copilot uses AI. Check for mistakes.
@EvenZhu 我们不应该依赖
所以我建议可以直接将 Taro 中的实现迁移到这里。 |
另外 |
增加eventCenter的原因如下:
这个Taro项目转换Next.js项目的插件,为了兼容SSR,去除了依赖于@taro/runtime的eventCenter。
我们的存量taro项目中,使用了Taro.eventCenter作为事件管理中心方案。由于存在大量的Taro.eventCenter相关API调用(如on、off、trigger等),如果对该项目进行SSR兼容性处理,需要自己实现一套完整的eventCenter方案,而且要对使用Taro.eventCenter的代码进行修改,或者使用其他方式替换变量。
但是无论哪种方式,都不如直接对该插件的taro api进行扩展方便。而且基于我对我们多个项目的了解和分析,发现Taro.eventCenter在多个项目中频繁使用,我对于taro api的扩展可以认为是一个通用性的解决方案。
因为对于插件的理解可能存在遗漏或者偏差,如果我的方案思路或者实现代码有问题,请随时联系我。感谢!