web-dev-qa-db-ja.com

共通の依存関係を持つTypeScriptプロジェクトを構成して、複数のプレーンJavaScript出力ファイルをビルドします

現在 Bot scripts一部のスクリプト を作成しています。 Bot Landは、マウスとキーボードでユニットを制御する代わりに、APIを介してボットを制御するコードを記述し、ボットが他のボットと戦うリアルタイム戦略ゲームです。 SC2のユニットに精通している場合は、瞬きストーカー、攻城戦車、衛生兵、ウルトラリスクに似たボットを作成できます。 (これはソフトウェアエンジニアにとって非常に楽しいゲームですが、それはこの質問の範囲外です。)

bot land

ボットコントロールには、複雑さが増す3つのレベルがあります。デフォルトのAI、 Scratch -likeプログラミング言語、およびBotLandScriptと呼ばれるJavaScriptの削減されたセットです。 BotLandScriptの組み込みエディターは妥当ですが、すべてのコードを1つの単一ファイルとしてアップロードし、どこにでもグローバルトップレベル関数を含める必要があります。当然、コードが長くなり始め、異なるボットが同じ機能を共有する場合、これはしばらくして痛みを伴い始めます。

programming environment

複数のボット用のコードの記述を容易にし、裸の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は、ボット間で共有される共通コードであり、(非TS)Bot Land APIのTypeScript定義を提供します。各ボットは独自のフォルダーを取得し、1つのファイルにはボットコードが含まれ、もう1つのファイルにはボイラープレートtsconfig.jsonが含まれます。

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

tsconfig.jsonがビルドされると、ボット自体から変換されたコードと、bot.js内のコードallを含む対応するcommon.jsが作成されます。このセットアップは、いくつかの理由で最適ではありません。特に、ボイラープレートの複製が大量に必要であり、新しいボットを追加するのが難しくなり、ボットごとに不要なコードが多く含まれ、各ボットを個別にビルドする必要があります。

ただし、 これまでの私の調査 に基づくと、私がやりたいことを簡単に行う方法はないようです。特に、新しいtsc -bオプションと参照の使用は機能しません。コードをモジュール化する必要があり、Bot Landはすべての関数がトップレベルで定義された単一のファイルを必要とするためです。

次のことをできるだけ多く達成するための最良の方法は何ですか?

  • 新しいボットを追加するために新しいボイラープレートは必要ありません(たとえば、ボットごとにtsconfig.jsonはありません)
  • 未使用のコードを出力しないようにするために、一般的な関数にはimportを使用しますが、その後...
  • すべての機能をボットランドの特定の形式で1つのファイルとして出力します
  • ボットごとに1つ、複数の出力ファイルを生成する単一のビルドステップ
  • おまけ:ビルドプロセスとVSコードの統合。現在、対応する定型文 tasks.json があり、各サブプロジェクトをビルドします。

答えはおそらくtscに加えてGruntのようなものに関係していると漠然と推測しますが、そのことについて確信が持てません。

10
Andrew Mao

これが私の attempt であなたの要件に答えます。

注目すべきファイル:

  • src/tsconfig-botland.jsonは、任意のbot.landスクリプト(types/bot-land/index.d.tsに移動したカスタム宣言を含む)の設定を保持します。私が使用したstrict設定を変更する場合があります。
  • src/tsconfig.jsonは、すべてのボットへの参照を保持します。これは、別のボットスクリプトを追加するときに編集するファイルです

ボットスクリプトは少なくとも2つのファイルです:ミニマリストのtsconfig.jsonと1つ以上の.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. ボットの名前でoutFileを編集するには、src/<newBotFolder>/tsconfig.jsonを編集します
  3. src/tsconfig.jsonを編集し、src/<newBotFolder>への参照を追加します

次のnpm/yarnスクリプトが設定されています。

  • buildすべてのボットを構築する
  • build-cleanは、buildを実行する前にbuildフォルダをクリアします
  • formatsrcの下にあるすべての.tsファイルでPrettierを実行するには
  • lintすべてのボットスクリプトでtslintチェックを実行する

次に、要件を実行します。

  • 新しいボットを追加するために新しいボイラープレートは必要ありません(たとえば、ボットごとにtsconfig.jsonはありません)

これを実現するには、ボットフォルダー/スクリプトを列挙するスクリプトを作成し、ボットごとに関連するtsconfig.jsonをセットアップしてtscを実行する必要があります。厳密に必要な場合を除き、最小限の設定(上記を参照)で十分な場合があります。

  • 未使用のコードの出力を回避するために一般的な関数のインポートを使用しますが、その後...

まず、モジュールexport/importステートメントの使用を開始する場合は、単一のファイル出力を実現するために、/ treehakeをパックする追加のサードパーティが必要になることに注意してください。私がBot.landについて収集できたことから、スクリプトはサーバー上で実行されています。デッドコードがボットのパフォーマンスに影響を与えない限り、私は本当に気にしません。

  • すべての機能をボットランドの特定の形式で1つのファイルとして出力します

できました。

  • ボットごとに1つ、複数の出力ファイルを生成する単一のビルドステップ

できました。

  • おまけ:ビルドプロセスとVSコードの統合。現在、各サブプロジェクトをビルドするための対応するボイラープレートtasks.jsonがあります。

npmスクリプトはvscのタスクリストに表示されるはずです(少なくとも私の場合はそうです)。したがって、tasks.jsonは不要になります。

2
PopGoesTheWza

実際にプロジェクト参照を使用できます。次の手順に従って、すべての関数を1つのファイルの最上位に配置して、元のファイルと同じ結果を得ます。しかし、ボットに必要な関数のみをインポートするソリューションは見つかりませんでした。つまり、インポートとエクスポートを使用しません。

ルートの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"
  ]
}

Tsがコンパイルエラーに悩まされないように、data.ts、motion.ts、utils.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
3
jperl