Для тех из нас, кто определенно не использует все части Phaser, было бы разумно уменьшить размер файла производственной библиотеки. Текущий размер уменьшенного файла составляет около 880 КБ. Это довольно много.

Хорошей новостью является то, что есть способ выбросить модули, которые вы не используете в своей игре, и это руководство проведет вас через этот процесс.

Хотя в Devlog 127 уже есть хорошее руководство о том, как это сделать, это руководство разработано, чтобы быть еще более подробными, пошаговыми инструкциями для людей, которые в целом знают, как создавать сценарии в играх, но мало работали с npm и / или webpack, и вам просто нужно четкое объяснение того, что делать, без дополнительного багажа изучения технологии, которая в противном случае была бы им не нужна.

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

Последнее, что следует отметить, это то, что я использую настольную систему Linux. Все должно быть одинаково для пользователей Windows и Mac OS, но если это не так, свяжитесь с нами.

Предпосылки

Вам понадобится npm, менеджер пакетов javascript. Независимо от того, в какой системе вы находитесь, установить npm несложно.

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

Пойдем!

Шаг 1. Клонируйте или загрузите специальное репо.

Это репозиторий, предоставленный Photonstorm (автор Phaser), который по сути является шаблоном для создания Phaser с помощью webpack. Вам не нужно ничего знать о webpack, чтобы следовать этому процессу.

Https://github.com/photonstorm/phaser3-custom-build

Клонируйте репозиторий или, если вы не знаете, как использовать git, просто возьмите zip-архив целиком и разархивируйте его в любом месте на вашем компьютере.

Не волнуйтесь, если к тому времени, когда вы доберетесь туда, репо будет выглядеть устаревшим. Это просто конфиг и не требует особых обновлений. Мы обязательно загрузим последнюю версию Phaser, используя эту настройку.

Шаг 2. Первоначальная настройка

Здесь мы настроим среду сборки и убедимся, что используем последнюю версию Phaser. Это очень простой процесс, который включает всего 2–3 команды в командной строке.

После распаковки архива вы получите папку «phaser3-custom-build-master». Перейдите в эту папку с помощью командной строки.

Теперь запустите эту команду:

npm install

Иногда после запуска вы получаете ошибку зависимости. В сообщении будет фактически объяснено, что для его устранения вам необходимо запустить

npm audit fix

В моем случае это устранило проблему, и я мог продолжить. (Обратите внимание, что npm audit fix доступен только в npm 6.1.0+)

Теперь давайте проверим версию Phaser, поставляемую с репозиторием:

npm list phaser

Это дает вам включенную версию Phaser. Если это не последняя версия, мы должны обновить Phaser, выполнив эту команду:

npm update phaser

Вот и все. Теперь вы готовы приступить к созданию Phaser!

Шаг 3. Сборка полной версии Phaser

Теперь у вас есть система, которая берет исходный код Phaser и создает окончательную библиотеку .js.

В корневом каталоге есть несколько файлов .js. Мы сосредоточимся только на файлах, которые начинаются с «phaser», например phaser-custom.js.

Что это за файлы, так это инструкции, которые сообщают веб-пакету, какие части Phaser нужно включить в сборку. Photonstorm подготовил для нас несколько предварительных настроек.

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

npm run [ALIAS]

Часть [ALIAS] зависит от того, какую версию вы хотите собрать. Итак, чтобы собрать полную версию Phaser со всеми включенными модулями, вам нужно будет запустить

npm run buildfull

Если вы хотите собрать только Phaser Core, запустите

npm run buildcore

Вы можете увидеть список этих псевдонимов в файле с именем «package.json».

На этом этапе вы хотите собрать полную версию Phaser и проверить, нормально ли работает ваша игра. Ну действуй

npm run buildfull

Это поместит недавно созданные файлы Phaser в папку «dist». Не беспокойтесь о ее очистке каждый раз, команды позаботятся об этом автоматически, сначала удалив всю папку «dist», а затем заменив ее новой.

Перейдя в папку «dist», вы увидите три файла: полную версию с комментариями и всем остальным, уменьшенную версию и файл карты.

Что вам нужно сделать, так это взять уменьшенную версию и скопировать ее в папку с игрой. Свяжите его, заменив стандартную библиотеку фазера в теге скрипта, и посмотрите, работает ли ваша игра.

Если нет - вам придется разобраться и, возможно, обратиться за помощью на канал Discord. Но если ваша игра использует ту же версию Phaser, которую указал npm list phaser, то итоговая библиотека должна быть идентична.

Шаг 4. Создание собственной версии Phaser

Предполагая, что полная версия работает, мы перейдем к созданию собственной версии.

Идея такова: мы берем полную версию Phaser и начинаем удалять модули, которые могут нам не понадобиться. Затем мы копируем модифицированную версию Phaser в нашу игру и убеждаемся, что игра работает. Если мы удалили модуль, необходимый для игры, игра не загрузится и выдаст ошибку в консоли Developer Tools. В этом случае мы просто добавляем модуль обратно. Цель этого - в конечном итоге уменьшить размер библиотеки.

Чтобы начать это делать, откройте файл «phaser-full.js». Это файл конфигурации для полной сборки, которую мы только что сделали. Скопируйте содержимое этого файла.

phaser-full.js:

require(‘polyfills’);
var CONST = require(‘const’);
var Extend = require(‘utils/object/Extend’);
/**
 * @namespace Phaser
 */
var Phaser = {
Actions: require(‘actions’),
 Animations: require(‘animations’),
 Cache: require(‘cache’),
 Cameras: require(‘cameras’),
 Core: require(‘core’),
 Class: require(‘utils/Class’),
 Create: require(‘create’),
 Curves: require(‘curves’),
 Data: require(‘data’),
 Display: require(‘display’),
 DOM: require(‘dom’),
 Events: require(‘events/EventEmitter’),
 Game: require(‘core/Game’),
 GameObjects: require(‘gameobjects’),
 Geom: require(‘geom’),
 Input: require(‘input’),
 Loader: require(‘loader’),
 Math: require(‘math’),
 Physics: require(‘physics’),
 Plugins: require(‘plugins’),
 Renderer: require(‘renderer’),
 Scale: require(‘scale’),
 Scene: require(‘scene/Scene’),
 Scenes: require(‘scene’),
 Sound: require(‘sound’),
 Structs: require(‘structs’),
 Textures: require(‘textures’),
 Tilemaps: require(‘tilemaps’),
 Time: require(‘time’),
 Tweens: require(‘tweens’),
 Utils: require(‘utils’)
};
Phaser = Extend(false, Phaser, CONST);
module.exports = Phaser;
global.Phaser = Phaser;

Затем откройте файл с названием «phaser-custom.js». Удалите все его содержимое и вставьте содержимое из «phaser-full.js». Это означает, что ваша индивидуальная сборка на данный момент будет идентична полной библиотеке Phaser.

С этого момента ваша сборка будет использовать «phaser-custom.js» в качестве файла конфигурации, а команда, которую вы будете использовать для сборки, будет следующей:

npm run build

В этом случае «build» - это псевдоним для конфигурации, которая у вас есть в «phaser-custom.js».

Итак, теперь в вашем «phaser-custom.js» найдите объект var Phaser. В нем перечислены модули. Вы удаляете модуль, просто удаляя один из элементов.

Например, предположим, что ваша игра представляет собой 2D-головоломку, в которой не используется физика. Это означает, что вы можете безопасно удалить элемент Physics: require(‘physics’) из объекта Phaser.

Я бы рекомендовал удалять объекты по одному, чтобы было легче понять, какой объект нужно вернуть, если ваша игра жалуется. Но можно удалить сразу несколько очевидных вещей сразу. Если ваша игра не рисует фигуры, не использует физику, DOM и анимацию, вполне безопасно удалить DOM, Geom, Physics и Tweens.

В любом случае, на данный момент процесс очень простой, хотя и немного утомительный: удалите модуль из «phaser-custom.js», затем запустите npm run build, затем перейдите в папку «dist», скопируйте минифицированную кастомную сборку для вашей игры и протестируйте ее.

Шаг 5. Очистка загрузчика и GameObjects.

Два модуля, которые вам, вероятно, всегда понадобятся, - это Loader и GameObjects (иначе зачем использовать Phaser?)

Однако часто вам не понадобятся все типы файлов или даже большинство типов файлов, а также не все игровые объекты.

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

5.1 Начнем с GameObjects.

Как мы узнаем, какие игровые объекты вообще существуют? Здесь на помощь приходит исходный код.

Перейдите в phaser3-custom-build-master / node_modules / phaser / src / gameobjects /

Каждая папка - это игровой объект. Теперь вы можете увидеть их все!

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

Идея состоит в том, чтобы расширить строку GameObjects: require(‘gameobjects’) на ингредиенты, чтобы мы могли перечислять только те объекты, которые нам нужны для нашей игры.

Итак, если мы хотим добавить игровые объекты Image, Sprite и Text, мы должны заменить строку GameObjects: require(‘gameobjects’) на это:

GameObjects: {
 DisplayList: require(‘gameobjects/DisplayList’),
 UpdateList: require(‘gameobjects/UpdateList’),
Image: require(‘gameobjects/image/Image’),
Sprite: require(‘gameobjects/sprite/Sprite’),
Text: require(‘gameobjects/text/static/Text’),
Factories: {
Image: require(‘gameobjects/image/ImageFactory’),
Sprite: require(‘gameobjects/sprite/SpriteFactory’),
Text: require(‘gameobjects/text/static/TextFactory’)
},
Creators: {
Image: require(‘gameobjects/image/ImageCreator’),
Sprite: require(‘gameobjects/sprite/SpriteCreator’),
Text: require(‘gameobjects/text/static/TextCreator’)
}
}

Это выглядит занятым, но в этом нет ничего сложного. На самом деле вы просто связываете игровые объекты из исходного кода, вот и все.

Итак, если вы хотите добавить еще один игровой объект, скажем, Group, просто имитируйте то, что делается с другими игровыми объектами в приведенном выше примере: вы связываете основной файл .js, скажем, group / Group, затем связываете его Factory, который находится в той же папке, group / GroupFactory, а затем его создателю, опять же, в той же папке в исходном коде, group / GroupCreator. Вот и все.

Убедитесь, что указаны правильные пути и все запятые есть, поскольку опечатка приведет к npm run build остановке из-за ошибки. Если ваши изменения все же привели к ошибке, внимательно проверьте файл еще раз. Например, типичной ошибкой является неправильное связывание текстового объекта, поскольку он имеет уникальный путь, а вместо обычного имени объекта / имени объекта путь фактически является текстом / статическим / текстовым. Поэтому не забудьте проверить все пути в самом исходном коде: phaser3-custom-build-master / node_modules / phaser / src / gameobjects /

Загрузчик 5.2

Вы, наверное, догадались, что с Loader все во многом похоже. Единственное отличие состоит в том, что синтаксис объекта Loader немного отличается. Вот пример:

Loader: {
 FileTypes: {
 ImageFile: require(‘loader/filetypes/ImageFile’),
 AudioFile: require(‘loader/filetypes/AudioFile’),
 SpriteSheetFile: require(‘loader/filetypes/SpriteSheetFile’),
 ScriptFile: require(‘loader/filetypes/ScriptFile’)
 },
 LoaderPlugin: require(‘loader/LoaderPlugin’)
 }

Обратите внимание, что вам необходимо потребовать LoaderPlugin в конце этой структуры. Но остальное не требует пояснений, и вы можете увидеть весь список типов файлов так же, как и для игровых объектов, перейдя в phaser3-custom-build-master / node_modules / phaser / src / loader / типы файлов /

Кстати, обратите внимание, что вы можете открыть некоторые из этих файлов .js и просмотреть их. Они хорошо комментируются, и вы можете быть удивлены, насколько легко следить за происходящим.

Пример

Вот пример того, как может выглядеть окончательный файл «phaser-custom.js»:

require(‘polyfills’);
var CONST = require(‘const’);
var Extend = require(‘utils/object/Extend’);
/**
 * @namespace Phaser
 */
var Phaser = {
Actions: require(‘actions’),
 Animations: require(‘animations’),
 Cache: require(‘cache’),
 Cameras: require(‘cameras’),
 Core: require(‘core’),
 Class: require(‘utils/Class’),
 Create: require(‘create’),
 Display: require(‘display’),
 Events: require(‘events/EventEmitter’),
 Game: require(‘core/Game’),
 //GameObjects: require(‘gameobjects’),
 GameObjects: {
 DisplayList: require(‘gameobjects/DisplayList’),
 UpdateList: require(‘gameobjects/UpdateList’),
Group: require(‘gameobjects/group/Group’),
 Image: require(‘gameobjects/image/Image’),
 Sprite: require(‘gameobjects/sprite/Sprite’),
 Text: require(‘gameobjects/text/static/Text’),
Factories: {
 Group: require(‘gameobjects/group/GroupFactory’),
 Image: require(‘gameobjects/image/ImageFactory’),
 Sprite: require(‘gameobjects/sprite/SpriteFactory’),
 Text: require(‘gameobjects/text/static/TextFactory’)
 
 },
Creators: {
 Group: require(‘gameobjects/group/GroupCreator’), 
 Image: require(‘gameobjects/image/ImageCreator’),
 Sprite: require(‘gameobjects/sprite/SpriteCreator’),
 Text: require(‘gameobjects/text/static/TextCreator’)
 
 }
 },
 Input: require(‘input’),
 Loader: {
 FileTypes: {
 ImageFile: require(‘loader/filetypes/ImageFile’),
 AudioFile: require(‘loader/filetypes/AudioFile’),
 SpriteSheetFile: require(‘loader/filetypes/SpriteSheetFile’),
 ScriptFile: require(‘loader/filetypes/ScriptFile’)
 },
 LoaderPlugin: require(‘loader/LoaderPlugin’)
 },
 Plugins: require(‘plugins’),
 Renderer: require(‘renderer’),
 Scale: require(‘scale’),
 Scene: require(‘scene/Scene’),
 Scenes: require(‘scene’),
 Sound: require(‘sound’)
};
Phaser = Extend(false, Phaser, CONST);
module.exports = Phaser;
global.Phaser = Phaser;

Вывод

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

Например, для моей игры мне удалось уменьшить размер файла со стандартных 884кб до 456кб. А поскольку Apache и другие веб-серверы обычно по умолчанию сжимают многие из этих файлов, размер файла фактически уменьшается с 233 КБ (сжатая gzip версия полной библиотеки) до 121 КБ (сжатая с помощью gzip версия моей пользовательской сборки).