如何在 1.3.0 版本之前的 Wonderland Engine 项目中启用 JavaScript 热重载。

JavaScript 热重载在 1.3.0 中的应用

Wonderland Engine 1.3.0 的发布引入了一种在编辑器中打包 JavaScript/TypeScript 应用的新方法。

新的设置允许编辑器重新支持热重载功能,即无需重启引擎和 VR 会话就能在浏览器中重新加载您的 JavaScript。

1.3.0 之前 

此前,编辑器从一个单一入口点(index.js)生成一个 JavaScript 包:

js/index.js

 1import {loadRuntime} from '@wonderlandengine/api';
 2
 3/* wle:auto-imports:start */
 4import {MyComponent} from './js/my-component.js';
 5/* wle:auto-imports:end */
 6
 7const engine = await loadRuntime(...);
 8
 9/* wle:auto-register:start */
10engine.registerComponent(MyComponent);
11/* wle:auto-register:end */

生成的包因此包含了导入的依赖引擎实例化代码,以及全局变量。

新架构 

新的架构将应用入口和组件注册分开:

  • js/index.js:包含组件注册
  • app.js:包含引擎创建、全局变量等…

js/index.js

 1// 组件入口点
 2
 3/* wle:auto-imports:start */
 4import {MyComponent} from './js/my-component.js';
 5/* wle:auto-imports:end */
 6
 7export default function(engine) {
 8  /* wle:auto-register:start */
 9  engine.registerComponent(MyComponent);
10  /* wle:auto-register:end */
11}

app.js

1// 应用入口点
2
3import {loadRuntime} from '@wonderlandengine/api';
4
5const engine = await loadRuntime(...);
6engine.loadMainScene('MyScene.bin');

此外,组件包将由 engine.loadMainScene() 调用自动下载并注册。

您可以手动导入组件并在应用中注册它们,但请先参考 Gotchas 部分以避免常见问题。

设置 

编辑器过去只在 JavaScript 设置中有一个入口:

如何选择 npm 脚本

现在分为了应用和组件入口:

JavaScript 热重载在 1.3.0 中的应用

output 设置用于指代部署文件夹中的包文件名。

当使用自定义 npm 命令时,此值必须设置为生成文件的文件名。

迁移 

打开 1.3 版本之前的项目时,迁移过程将禁用组件包,并保留在原始索引中的导入列表。

迁移包括以下几个步骤:

  • Project Settings 中启用组件打包
  • 将组件的导入/注册移至新索引文件

启用组件包 

Project Settings 中:

  • 如果未选中,勾选 Show Advanced Settings 复选框
  • 设置 bundling 选项。我们推荐使用 esbuild
  • entryPoint 设置为 js/component-index.js
  • output 设置为 MyWonderland-components.js
JavaScript 热重载在 1.3.0 中的应用

打包将自动生成 js/component-index.js

1/* wle:auto-imports:start */
2/* wle:auto-imports:end */
3
4export default function(engine) {
5/* wle:auto-register:start */
6/* wle:auto-register:end */
7}

移动组件 

如果您的项目在旧的 js/index.js 文件中手动导入/注册了组件,这些需要移至 js/component-index.js 入口点:

js/index.js

 1import {loadRuntime} from '@wonderlandengine/api';
 2
 3/* wle:auto-imports:start */
 4/* wle:auto-imports:end */
 5
 6// 这一行必须移至组件包
 7import {ManualComponent} from './js/manual-component.js';
 8
 9const engine = await loadRuntime(...);
10
11/* wle:auto-register:start */
12/* wle:auto-register:end */
13
14// 这一行必须移至组件包
15engine.registerComponent(ManualComponent);

js/component-index.js

 1/* wle:auto-imports:start */
 2/* wle:auto-imports:end */
 3
 4import {ManualComponent} from './manual-component.js';
 5
 6export default function(engine) {
 7    /* wle:auto-register:start */
 8    /* wle:auto-register:end */
 9    engine.registerComponent(ManualComponent);
10}

恭喜,您现在已使用新架构!

注意事项(Gotchas) 

具有全局变量的应用程序可能会遇到以下情况:

js/manager.js

1export class Manager {
2    static isReady = false;
3}

app.js

1import {loadRuntime} from '@wonderlandengine/api';
2import {Manager} from './js/manager.js';
3
4const engine = await loadRuntime(...);
5Manager.isReady = true;
6engine.loadMainScene('MyScene.bin');

js/my-component.js

1import {Manager} from './manager.js';
2
3export class MyComponent extends Component {
4    start() {
5        console.log(Manager.isReady); // `false`
6    }
7}

在此示例中,Manager 类将在每个文件中声明一次。

关于如何架构应用程序的决策将因用例而异。以下是一些潜在的迁移步骤:

  • 管理器可以完全移至组件包一侧
  • 全局变量可以延迟初始化
  • 可以使用 window 共享数据(不太推荐)
  • 对于高级用户:可以使用单独的 js 包并在 html 中导入
Last Update: February 5, 2025

保持更新。