Настройте проект TypeScript с общими зависимостями для создания нескольких простых выходных файлов JavaScript

10

В настоящее время я пишу несколько сценариев для Bot Land . Bot Land - это стратегия в реальном времени, в которой вместо управления своими юнитами с помощью мыши и клавиатуры вы пишете код для управления своими ботами через API, а затем ваши боты начинают сражаться с ботами других. Если вы знакомы с юнитами в SC2, вы можете создавать ботов, похожих на мигающих сталкеров, осадных танков, медиков и ультралисков. (Это довольно забавная игра для разработчиков программного обеспечения, но это выходит за рамки этого вопроса.)

бот-лэнд

Элемент управления Bot имеет три уровня возрастающей сложности: AI по умолчанию, Scratch- подобный язык программирования и сокращенный набор JavaScript, называемый BotLandScript. Хотя встроенный редактор для BotLandScript является разумным, вы должны загрузить весь свой код в виде одного файла с глобальными функциями верхнего уровня повсюду. Естественно, через некоторое время это начинает становиться болезненным, если ваш код начинает становиться длинным и разные боты совместно используют одни и те же функции.

среда программирования

Чтобы упростить написание кода для нескольких ботов, уменьшить вероятность непреднамеренных ошибок при кодировании на голом JS и увеличить мои шансы побить других игроков, я настроил вышеупомянутый проект TypeScript, чтобы предоставить общую библиотеку, а также код для каждого из моих ботов. , Текущая структура каталогов выглядит примерно так:

lib/ 
  bot.land.d.ts
  common.ts
BlinkStalker/
  BlinkStalker.ts
  tsconfig.json
Artillery/
  Artillery.ts
  tsconfig.json
SmartMelee/
  SmartMelee.ts
  tsconfig.json

libэто общий код, который используется совместно ботами и предоставляет определения TypeScript для API-интерфейса Bot Land (не TS). Затем каждый бот получает свою собственную папку, в которой один файл содержит код бота, а другой - шаблон tsconfig.json:

{
  "compilerOptions": {
    "target": "es3",
    "module": "none",
    "sourceMap": false,
    "outFile": "bot.js"
  },
  "files": [
    "MissileKite.ts"
  ],
  "include": [
    "../lib/**/*"
  ]
}

Когда каждый собран tsconfig.json, он создает соответствующий, bot.jsкоторый содержит переданный код от самого бота, а также весь код в common.js. Эта настройка является неоптимальной по нескольким причинам, среди прочего: она требует большого количества дубликатов, затрудняет добавление новых ботов, включает в себя много ненужного кода для каждого бота и требует, чтобы каждый бот создавался отдельно.

Однако, основываясь на моих исследованиях , не кажется, что есть простой способ сделать то, что я хочу. В частности, использование новой tsc -bопции и ссылок не работает, потому что для этого требуется, чтобы код был модульным, а Bot Land требует одного файла со всеми функциями, определенными на верхнем уровне.

Каков наилучший способ достичь как можно большего числа следующих действий?

  • Не требуется новый шаблон для добавления нового бота (например, нет tsconfig.jsonна бот)
  • Используйте importдля общих функций, чтобы избежать вывода неиспользуемого кода, но затем ...
  • По-прежнему выводить все функции в виде одного файла в определенном формате Bot Land
  • Один шаг сборки, который создает несколько выходных файлов, по одному для каждого бота
  • Бонус: интеграция процесса сборки с VS Code. В настоящее время существует соответствующий шаблон tasks.jsonдля строительства каждого подпроекта.

Я смутно предполагаю, что ответ, вероятно, включает в себя что-то вроде Гранта tsc, но я не знаю достаточно об этом, чтобы быть уверенным.

Эндрю Мао
источник
Необходимо, чтобы у всех ботов были отдельные папки? Или достаточно того, что каждый бот находится на корневом уровне в одном файле? (например <root>/MissileKite.ts)
13
1
Все ли передаваемые бот-файлы должны быть названы bot.js?
13
Корень в одном файле будет предпочтительнее; они находятся в отдельных папках из-за отдельных tsconfig.json. Транспортируемые файлы ботов могут быть названы как угодно, желательно в формате .js исходного файла. У меня это настроено сейчас в репо с выводом на build/MissileKite.js.
Эндрю Мао
1
@ andrew-mao Вы можете взглянуть на мой шаблон для проектов GAS, который отвечает большинству ваших требований (но ориентирован на другую среду). Если он вам подходит, возможно, я смогу адаптировать его для вас на следующей неделе. github.com/PopGoesTheWza/ts-gas-project-starter
PopGoesTheWza
Есть ли tsconfig-gas.jsonна что посмотреть?
Андрей Мао

Ответы:

2

Вот моя попытка ответить на ваши требования.

Известные файлы:

  • src/tsconfig-botland.jsonсодержит настройки для любого скрипта bot.land (включая ваши пользовательские объявления, на которые я перешел types/bot-land/index.d.ts). Вы можете изменить strictнастройки, которые я использовал.
  • src/tsconfig.jsonсодержит ссылки на всех ваших ботов. Это файл для редактирования всякий раз, когда вы хотите добавить другой скрипт бота

Сценарий бота представляет собой как минимум два файла: минималистский tsconfig.jsonи один или несколько .tsфайлов сценария.

Например src/AggroMiner/tsconfig.json:

{
    "extends": "../tsconfig-botland",
    "compilerOptions": {
        "outFile": "../../build/AggroMiner.js"
    },
    "files": ["index.ts"],
    "include": ["**/*.ts", "../lib/**/*.ts"]
}

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

  1. скопировать любую папку бота (т.е. src/AggroMiner) в новую папку вsrc
  2. редактировать, src/<newBotFolder>/tsconfig.jsonчтобы редактировать outFileс именем вашего бота
  3. отредактируйте src/tsconfig.jsonи добавьте ссылку наsrc/<newBotFolder>

Следующее npm/ yarnскрипт был установлен:

  • build собрать всех ботов
  • build-cleanкоторые очищают buildпапку перед запускомbuild
  • formatзапустить Prettier для всех .tsфайлов вsrc
  • lint запустить проверку tslint на всех скриптах бота

Теперь выполняем ваши требования:

  • Для добавления нового бота не требуется новый шаблон (например, нет tsconfig.json на бот)

Для этого потребуется создать какой-нибудь скрипт, который будет перечислять вашу папку / скрипты ботов ... и настраивать соответствующий бот tsconfig.jsonи запускать tsc. Если это не является строго необходимым, минимальной установки (описанной выше) может быть достаточно.

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

Во-первых, имейте в виду, что если вы начнете использовать какой-либо модуль export/ importоператоры, вам понадобится дополнительная сторонняя программа для упаковки / treehake, чтобы добиться вывода одного файла. Из того, что я мог собрать из Bot.land, ваши скрипты работают на сервере. Если бы deadcode не повлиял на производительность вашего бота, я бы не стал беспокоиться.

  • По-прежнему выводить все функции в виде одного файла в определенном формате Bot Land

Выполнено.

  • Один шаг сборки, который создает несколько выходных файлов, по одному для каждого бота

Выполнено.

  • Бонус: интеграция процесса сборки с VS Code. В настоящее время существует соответствующий шаблон tasks.json для создания каждого подпроекта.

В npmсценарии должен появиться в списке задач VSC (по крайней мере они делают в шахте) , таким образом , делая tasks.jsonненужным.

PopGoesTheWza
источник
Deadcode - это хороший компромисс для всего, что вы здесь сделали; Можете ли вы дать мне знать, почему вы использовали types/bot-landопределения и почему выбрали strictнастройки?
Эндрю Мао
Типы / bot-land / index.d.ts действительно являются вашими оригинальными .d.ts из lib, переименованными и размещенными по-другому. Î предположим, что он как бы описывает общий контекст выполнения bot.land для всех скриптов, и поэтому я уверен, что он всегда доступен в каждом скрипте бота. «Строгие» настройки присутствуют только здесь, потому что я лениво скопировал мои любимые настройки (то же самое для более хороших настроек). Они должны быть адаптированы к предпочтениям пользователя (вас).
PopGoesTheWza
Мне просто интересно, есть ли обычная причина для того, чтобы это включить, typesили это был просто особый способ организации, который вы выбрали.
Эндрю Мао
Единственная причина в том, что предполагалось, что это был контекст bot.land. Подумайте об этом, как о том, что @ types / node typings уже доступны в ваших скриптах
nodejs
1
Папка / types является одним из общепринятых мест, где размещаются объявления внешних типов (т. Е. Специфический контекст выполнения, такой как механизм Botland или нетипизированные модули / пакеты JavaScript, которые здесь не используются)
PopGoesTheWza,
3

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

В вашем tsconfig.json в корне

{
    "files": [],
    "references": [
        { "path": "./lib" }
        { "path": "./AggroMiner" }
        { "path": "./ArtilleryMicro" }
        { "path": "./MissileKite" }
        { "path": "./SmartMelee" }
        { "path": "./ZapKite" }
    ]
}

Затем, в вашей папке lib, добавьте tsconfig.json как

{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "composite": true,
    "rootDir": ".",
    "outFile": "../build/lib.js",
    "target": "es3",
    "removeComments": true,
    "sourceMap": false,
  },
  "files": [
    "data.ts",
    "movement.ts",
    "utils.ts"
  ]
}

Нам нужно внести некоторые изменения в data.ts, motion.ts и utils.ts, чтобы ts не беспокоил нас ошибками компиляции.

data.ts

/// <reference path="./bot.land.d.ts"/>

(...)

movement.ts


/// <reference path="./data.ts"/>
/// <reference path="./utils.ts"/>
(...)

utils.ts

/// <reference path="./bot.land.d.ts"/>
(...)

Затем мы добавляем base.json в корень (tsconfig.json ботов расширит его).

base.json

{
  "compilerOptions": {
    "declaration": true,
    "composite": true,
    "rootDir": ".",
    "target": "es3",
    "removeComments": true,
    "sourceMap": false,
  }
}

и боты 'tsconfig.json (адаптируются в соответствии с ботами)

{
  "extends": "../base",
  "compilerOptions": {
    "outFile": "../build/AggroMiner.js",
  },
  "files": [
    "AggroMiner.ts"
  ],
  "references": [
      { "path": "../lib", "prepend": true } //note the prepend: true
  ]
}

Вот и все. Теперь просто беги

tsc -b
jperl
источник
Поэтому я подумал о чем-то подобном, но причина, по которой это не работает, заключается в том, что файл, который выводится на вашу ветку, имеет кучу подобных вещей в верхней части, и игре нужен один файл со всеми функциями в нем. Поэтому мне пришлось бы вручную скомпоновать все скомпилированные выходные данные, чтобы создать загружаемый файл, а не просто скопировать его. `" использовать строгое "; export .__ esModule = true; var data_1 = require ("../ lib / data"); var motion_1 = require ("../ lib / движение"); var utils_1 = require ("../ lib / utils"); `
Эндрю Мао
Но это работает, поскольку lib также выводится (встраивается) в папку build (благодаря ссылкам).
jperl
Я был в процессе редактирования моего комментария - см. Выше. Или посмотрите на то, build/MissileKite.jsчто выводится при построении исходного репо.
Эндрю Мао
@ AndrewMao извините, только теперь я понимаю, что вы имели в виду, «потому что для этого требуется, чтобы код был модульным, а Bot Land - один файл со всеми функциями, определенными на верхнем уровне». Я думал об использовании «prepend: true», но это требует использования outFile, и ts не позволит нам скомпилировать файлы в lib, поскольку некоторые зависят от других.
jperl
@AndrewMao Я добавил поддержку Webpack. Я отредактировал пост и внес изменения в репо. Дайте мне знать, если это будет лучше.
jperl