diff --git a/.changeset/fix-esm-require-bug.md b/.changeset/fix-esm-require-bug.md new file mode 100644 index 00000000..cac76df4 --- /dev/null +++ b/.changeset/fix-esm-require-bug.md @@ -0,0 +1,11 @@ +--- +"@esengine/ecs-framework": patch +--- + +fix(ecs): 修复 ESM 环境下 require 不存在的问题 + +- 新增 `RuntimeConfig` 模块,作为运行时环境配置的独立存储 +- `Core.runtimeEnvironment` 和 `Scene.runtimeEnvironment` 现在都从 `RuntimeConfig` 读取 +- 移除 `Scene.ts` 中的 `require()` 调用,解决 Node.js ESM 环境下的兼容性问题 + +此修复解决了在 Node.js ESM 环境(如游戏服务端)中使用 `scene.isServer` 时报错 `ReferenceError: require is not defined` 的问题。 diff --git a/packages/framework/core/src/Core.ts b/packages/framework/core/src/Core.ts index 5191f927..12df4bca 100644 --- a/packages/framework/core/src/Core.ts +++ b/packages/framework/core/src/Core.ts @@ -16,6 +16,7 @@ import { IPlugin } from './Core/Plugin'; import { WorldManager } from './ECS/WorldManager'; import { DebugConfigService } from './Utils/Debug/DebugConfigService'; import { createInstance } from './Core/DI/Decorators'; +import { RuntimeConfig } from './RuntimeConfig'; /** * @zh 游戏引擎核心类 @@ -86,14 +87,20 @@ export class Core { * Core.create({ runtimeEnvironment: 'server' }); * ``` */ - public static runtimeEnvironment: RuntimeEnvironment = 'standalone'; + public static get runtimeEnvironment(): RuntimeEnvironment { + return RuntimeConfig.runtimeEnvironment; + } + + public static set runtimeEnvironment(value: RuntimeEnvironment) { + RuntimeConfig.runtimeEnvironment = value; + } /** * @zh 是否在服务端运行 * @en Whether running on server */ public static get isServer(): boolean { - return Core.runtimeEnvironment === 'server'; + return RuntimeConfig.isServer; } /** @@ -101,7 +108,7 @@ export class Core { * @en Whether running on client */ public static get isClient(): boolean { - return Core.runtimeEnvironment === 'client'; + return RuntimeConfig.isClient; } /** diff --git a/packages/framework/core/src/ECS/Scene.ts b/packages/framework/core/src/ECS/Scene.ts index a63c7e1d..4779a10d 100644 --- a/packages/framework/core/src/ECS/Scene.ts +++ b/packages/framework/core/src/ECS/Scene.ts @@ -13,6 +13,7 @@ import { QuerySystem } from './Core/QuerySystem'; import { TypeSafeEventSystem } from './Core/EventSystem'; import { ReferenceTracker } from './Core/ReferenceTracker'; import { IScene, ISceneConfig, RuntimeEnvironment } from './IScene'; +import { RuntimeConfig } from '../RuntimeConfig'; import { getComponentInstanceTypeName, getSystemInstanceTypeName, getSystemMetadata, getSystemInstanceMetadata } from './Decorators'; import { TypedQueryBuilder } from './Core/Query/TypedQuery'; import { @@ -200,10 +201,7 @@ export class Scene implements IScene { if (this._runtimeEnvironmentOverride) { return this._runtimeEnvironmentOverride; } - // 动态导入避免循环依赖 - // eslint-disable-next-line @typescript-eslint/no-require-imports - const { Core } = require('../Core') as typeof import('../Core'); - return Core.runtimeEnvironment; + return RuntimeConfig.runtimeEnvironment; } /** diff --git a/packages/framework/core/src/RuntimeConfig.ts b/packages/framework/core/src/RuntimeConfig.ts new file mode 100644 index 00000000..6d619a58 --- /dev/null +++ b/packages/framework/core/src/RuntimeConfig.ts @@ -0,0 +1,50 @@ +import type { RuntimeEnvironment } from './Types'; + +/** + * @zh 全局运行时配置 + * @en Global runtime configuration + * + * @zh 独立模块,避免 Core 和 Scene 之间的循环依赖 + * @en Standalone module to avoid circular dependency between Core and Scene + */ +class RuntimeConfigClass { + private _runtimeEnvironment: RuntimeEnvironment = 'standalone'; + + /** + * @zh 获取运行时环境 + * @en Get runtime environment + */ + get runtimeEnvironment(): RuntimeEnvironment { + return this._runtimeEnvironment; + } + + /** + * @zh 设置运行时环境 + * @en Set runtime environment + */ + set runtimeEnvironment(value: RuntimeEnvironment) { + this._runtimeEnvironment = value; + } + + /** + * @zh 是否在服务端运行 + * @en Whether running on server + */ + get isServer(): boolean { + return this._runtimeEnvironment === 'server'; + } + + /** + * @zh 是否在客户端运行 + * @en Whether running on client + */ + get isClient(): boolean { + return this._runtimeEnvironment === 'client'; + } +} + +/** + * @zh 全局运行时配置单例 + * @en Global runtime configuration singleton + */ +export const RuntimeConfig = new RuntimeConfigClass(); diff --git a/packages/framework/core/src/index.ts b/packages/framework/core/src/index.ts index d137a364..a8ce0b9c 100644 --- a/packages/framework/core/src/index.ts +++ b/packages/framework/core/src/index.ts @@ -5,6 +5,7 @@ // 核心模块 export { Core } from './Core'; +export { RuntimeConfig } from './RuntimeConfig'; export { ServiceContainer, ServiceLifetime } from './Core/ServiceContainer'; export type { IService, ServiceType, ServiceIdentifier } from './Core/ServiceContainer';