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


10

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

ボットランド

ボット制御には、3つのレベルの複雑さの増加があります。デフォルトのAI、スクラッチのようなプログラミング言語、およびBotLandScriptと呼ばれるJavaScriptの削減されたセットです。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ボット間で共有される共通コードであり、(TS以外の)ボットランド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ボット自体ならびにからそれがtranspiled含むコードのすべてのコードでのcommon.jsます。このセットアップは、いくつかの理由で最適ではありません。特に、ボイラープレートの複製が大量に必要であり、新しいボットを追加するのが難しくなり、ボットごとに不要なコードが多く含まれ、各ボットを個別にビルドする必要があります。

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

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

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

答えはおそらくに加えてGruntのようなものを含んでいるのではないかと漠然と推測しますtscが、確かにそれについて十分に知りません。


すべてのボットに個別のフォルダーが必要ですか?または、各ボットが単一のファイルのルートレベルにあれば十分ですか?(例<root>/MissileKite.ts
a1300 '10 / 10/19

1
変換されたすべてのボットファイルには名前を付ける必要がありますbot.jsか?
a1300 '10 / 10/19

単一ファイルのルートが望ましいでしょう。別々のため、それらは別々のフォルダにありますtsconfig.json。分解されたボットファイルには任意の名前を付けることができ、できれば元のファイルの.jsバージョンを使用できます。に出力するレポで、このように設定しましたbuild/MissileKite.js
Andrew Mao

1
@ andrew-mao要件のほとんどに対処する(ただし、別の環境を対象とする)GASプロジェクトのテンプレートを一見することができます。それがあなたに合っている場合は、来週中にそれを適応させることができるかもしれません。github.com/PopGoesTheWza/ts-gas-project-starter
PopGoesTheWza

あるtsconfig-gas.jsonそこを見て、関連する事は?
Andrew Mao

回答:


2

ここにあなたの要求に答える私の試みがあります。

注目すべきファイル:

  • src/tsconfig-botland.jsonbot.landスクリプト(私がに移動したカスタム宣言を含む)の設定を保持しますtypes/bot-land/index.d.tsstrict私が使用した設定を変更する場合があります。
  • 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. ボットの名前でsrc/<newBotFolder>/tsconfig.jsonを編集するには、を編集しoutFileます
  3. src/tsconfig.jsonへの参照を編集して追加するsrc/<newBotFolder>

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

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

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

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

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

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

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

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

できました。

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

できました。

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

npmスクリプトは、このようにすること(少なくとも、彼らは鉱山で行う)VSCのタスクリストに表示されますtasks.json不要に。


デッドコードは、あなたがここで行った他のすべてのための素晴らしい妥協です。なぜtypes/bot-land定義に使用したのか、なぜstrict設定を選択したのか教えてください。
Andrew Mao

Types / bot-land / index.d.tsは、実際にはlibの元の.d.tsであり、名前が変更され、配置が異なります。allすべてのスクリプトの一般的なbot.land実行コンテキストを説明していると想定して、すべてのボットスクリプトで常に使用できることを確認します。「厳格な」設定はここにのみあります。好きな設定を遅延コピーしたためです(よりきれいな設定と同じです)。これらは、ユーザー(ユーザー)の好みに合わせて調整する必要があります。
PopGoesTheWza

それを入れる通常の理由があるのtypesか、それがあなたが選んだものを整理するための特定の方法にすぎないのかと思っています。
Andrew Mao

唯一の理由は、それがbot.landコンテキストであると想定していることです。@ types / node型付けがnodejsスクリプトで既に利用可能であると考えてください
PopGoesTheWza

1
A /タイプフォルダ1つのプット外部タイプ宣言(ここで使用されていないbotlandエンジンまたは型なしJavaScriptのモジュール/パッケージのようなIEの特定の実行コンテキスト)は、従来の場所の一つである
PopGoesTheWza

3

実際にプロジェクト参照を使用できます。次の手順に従って、すべての関数を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、movement.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

だから私はこのようなものを考えましたが、それが機能しない理由は、ブランチに出力されるファイルの一番上にこのようなものがたくさんあり、ゲームにはすべての関数が含まれた1つのファイルが必要だからです。そのため、ファイルをコピーして貼り付けるのではなく、すべてのコンパイル済み出力を手動でまとめて、アップロードするファイルを作成する必要があります。`「厳密に使用」; exports .__ esModule = true; var data_1 = require( "../ lib / data"); var Movement_1 = require( "../ lib / movement"); var utils_1 = require( "../ lib / utils"); `
Andrew Mao

しかし、libもビルドフォルダーに出力(ビルド)されるため、機能します(参照のおかげで)。
jperl

私はコメントを編集している最中でした-上記を参照してください。またはbuild/MissileKite.js、元のリポジトリをビルドするときに出力されるを見てください。
Andrew Mao

@AndrewMao申し訳ありませんが、「コードをモジュール化する必要があり、Bot Landはすべての関数がトップレベルで定義された単一のファイルを必要とするため」ということで、私はあなたの意図を理解しました。「prepend:true」を使用することを考えましたが、outFileを使用する必要があり、tsはlib内のファイルをコンパイルできません。
jperl

@AndrewMao Webpackサポートを追加しました。私は投稿を編集し、変更をリポジトリにプッシュしました。それが良いかどうか教えてください。
jperl
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.