增加支持客户端的eventCenter代理类,解决从@tarojs/taro导入的eventCenter为空的问题#47
增加支持客户端的eventCenter代理类,解决从@tarojs/taro导入的eventCenter为空的问题#47EvenZhu wants to merge 1 commit intoNervJS:mainfrom
Conversation
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
The parameter 'method' should have a type annotation. Consider adding ': string' to specify the expected parameter type.
| createProxyMethod(method) { | |
| createProxyMethod(method: string) { |
| const loadEventCenter = promisify( | ||
| limited.async('loadEventCenter', this.loadEventCenter) | ||
| ) | ||
| loadEventCenter() // 触发加载 |
There was a problem hiding this comment.
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拒绝 |
| interface EventCenterProxy { | ||
| ready: boolean | ||
| eventCenter: any | ||
| pendingCalls: any[] |
There was a problem hiding this comment.
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[] |
| } | ||
|
|
||
| // 加载真实eventCenter | ||
| async loadEventCenter() { |
There was a problem hiding this comment.
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.
|
@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的扩展可以认为是一个通用性的解决方案。
因为对于插件的理解可能存在遗漏或者偏差,如果我的方案思路或者实现代码有问题,请随时联系我。感谢!