Skip to content

Conversation

EvenZhu
Copy link
Contributor

@EvenZhu EvenZhu commented Sep 9, 2025

增加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的扩展可以认为是一个通用性的解决方案。

因为对于插件的理解可能存在遗漏或者偏差,如果我的方案思路或者实现代码有问题,请随时联系我。感谢!

@SyMind SyMind requested a review from Copilot September 10, 2025 11:47
Copy link

@Copilot Copilot AI left a 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) {
Copy link

Copilot AI Sep 10, 2025

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.

Suggested change
createProxyMethod(method) {
createProxyMethod(method: string) {

Copilot uses AI. Check for mistakes.

const loadEventCenter = promisify(
limited.async('loadEventCenter', this.loadEventCenter)
)
loadEventCenter() // 触发加载
Copy link

Copilot AI Sep 10, 2025

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.

Suggested change
loadEventCenter() // 触发加载
loadEventCenter().catch(() => {}) // 触发加载,避免未处理的promise拒绝

Copilot uses AI. Check for mistakes.

Comment on lines +12 to +15
interface EventCenterProxy {
ready: boolean
eventCenter: any
pendingCalls: any[]
Copy link

Copilot AI Sep 10, 2025

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.

Suggested change
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() {
Copy link

Copilot AI Sep 10, 2025

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.

@SyMind
Copy link
Member

SyMind commented Sep 10, 2025

@EvenZhu 我们不应该依赖 @tarojs/runtime,这可能会引入未知问题

  1. 插件中的逻辑要要同时运行在 server 和 client 中,@tarojs/runtime 不保证这一点
  2. @tarojs/runtime 会引入不受控的其他依赖

所以我建议可以直接将 Taro 中的实现迁移到这里。

@SyMind
Copy link
Member

SyMind commented Sep 10, 2025

另外 Taro.* 的 API 缺失都算 bug,即使不支持也应当报不支持的错误。

@EvenZhu EvenZhu closed this Sep 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants