JavaScript Hot-Reload в версии 1.3.0

Дэвид Пейшо

В релизе Wonderland Engine 1.3.0 представлена новая схема упаковки JavaScript/TypeScript приложения в редакторе.

Новая настройка позволяет редактору вернуть поддержку Hot Reload, т.е. перезагружать ваш JavaScript в браузере без перезапуска движка и VR-сессий.

До 1.3.0 

Ранее редактор создавал единый JavaScript-бандл, с одной точкой входа (index.js):

js/index.js

import {loadRuntime} from '@wonderlandengine/api';

/* wle:auto-imports:start */
import {MyComponent} from './js/my-component.js';
/* wle:auto-imports:end */

const engine = await loadRuntime(...);

/* wle:auto-register:start */
engine.registerComponent(MyComponent);
/* wle:auto-register:end */

Таким образом, созданный бандл содержал импортированные зависимости, код инициализации движка, а также глобальные переменные.

Новая архитектура 

Новая архитектура разделяет точку входа приложения от регистрации компонентов:

  • js/index.js: Содержит регистрацию компонентов
  • app.js: Содержит создание движка, глобальные переменные и т.д.

js/index.js

// Точка входа для компонентов

/* wle:auto-imports:start */
import {MyComponent} from './js/my-component.js';
/* wle:auto-imports:end */

export default function(engine) {
  /* wle:auto-register:start */
  engine.registerComponent(MyComponent);
  /* wle:auto-register:end */
}

app.js

// Точка входа для приложения

import {loadRuntime} from '@wonderlandengine/api';

const engine = await loadRuntime(...);
engine.loadMainScene('MyScene.bin');

Кроме того, бандл компонентов будет автоматически загружен и зарегистрирован вызовом engine.loadMainScene().

Вы можете вручную импортировать компоненты и регистрировать их в приложении, но для начала ознакомьтесь с разделом Подводные камни, чтобы избежать распространенных ошибок.

Настройки 

Ранее редактор имел единственную запись для настроек JavaScript:

Как выбрать npm скрипт

Теперь она дублируется для точки входа приложения и компонентов:

Как выбрать npm скрипт

Настройка output используется для указания имени файла бандла в папке деплоя.

При использовании пользовательской команды npm, это значение должно быть установлено в имя созданного файла.

Миграция 

При открытии проекта до версии 1.3, процесс миграции отключит бандл компонентов и оставит список импортов в оригинальном индексе.

Миграция состоит из нескольких шагов:

  • Включите упаковку компонентов в Настройках Проекта
  • Переместите импорт/регистрацию компонентов в новый индексный файл

Включение упаковки компонентов 

В Настройках Проекта:

  • Поставьте галочку Показать Расширенные Настройки, если не стоит
  • Установите bundling опцию. Рекомендуется использовать esbuild
  • Установите entryPoint на js/component-index.js
  • Установите output на MyWonderland-components.js
Как выбрать npm скрипт

Упаковка автоматически создаст js/component-index.js:

/* wle:auto-imports:start */
/* wle:auto-imports:end */

export default function(engine) {
/* wle:auto-register:start */
/* wle:auto-register:end */
}

Перемещение компонентов 

Если в вашем проекте вручную импортировались/регистрировались компоненты в старом файле js/index.js, их нужно будет переместить в файл точки входа js/component-index.js:

js/index.js

import {loadRuntime} from '@wonderlandengine/api';

/* wle:auto-imports:start */
/* wle:auto-imports:end */

// Эта строка должна быть перенесена в бандл компонентов
import {ManualComponent} from './js/manual-component.js';

const engine = await loadRuntime(...);

/* wle:auto-register:start */
/* wle:auto-register:end */

// Эта строка должна быть перенесена в бандл компонентов
engine.registerComponent(ManualComponent);

js/component-index.js

/* wle:auto-imports:start */
/* wle:auto-imports:end */

import {ManualComponent} from './manual-component.js';

export default function(engine) {
    /* wle:auto-register:start */
    /* wle:auto-register:end */
    engine.registerComponent(ManualComponent);
}

Поздравляем, теперь вы используете новую архитектуру!

Подводные камни 

Приложения с глобальными переменными могут столкнуться со следующим сценарием:

js/manager.js

export class Manager {
    static isReady = false;
}

app.js

import {loadRuntime} from '@wonderlandengine/api';
import {Manager} from './js/manager.js';

const engine = await loadRuntime(...);
Manager.isReady = true;
engine.loadMainScene('MyScene.bin');

js/my-component.js

import {Manager} from './manager.js';

export class MyComponent extends Component {
    start() {
        console.log(Manager.isReady); // `false`
    }
}

В этом примере класс Manager будет объявлен по одному разу в каждом файле.

Решение о том, как проектировать приложение, будет различаться в каждом конкретном случае. Вот список возможных шагов по миграции:

  • Менеджеры могут быть полностью перенесены на сторону бандла компонентов
  • Глобальные переменные могут быть инициализированы лениво
  • Данные могут быть переданы с использованием window (менее рекомендуется)
  • Для опытных пользователей: Использовать отдельный js-бандл, импортированный в html.
Last Update: February 5, 2025

Будьте в курсе.