代码之家  ›  专栏  ›  技术社区  ›  Andrew Mao

使用公共依赖项配置TypeScript项目以生成多个纯JavaScript输出文件

  •  1
  • Andrew Mao  · 技术社区  · 6 年前

    我正在写 some scripts 对于 Bot Land . Bot Land是一个实时策略游戏,在这里,你不用鼠标和键盘控制你的单位,而是通过API编写代码来控制你的机器人,然后你的机器人去对抗别人的机器人。如果你熟悉SC2中的单位,你可以创建类似于眨眼跟踪者、攻城坦克、医疗兵和超级尖牙兽的机器人。(这对软件工程师来说是一个很有趣的游戏,但这不在这个问题的范围之内。)

    bot land

    BOT控件具有三个层次的复杂度:默认AI,A Scratch -类似于编程语言,以及一组被称为BotLandScript的简化JavaScript。虽然BotLandScript的内置编辑器是合理的,但是您必须将所有代码作为 一个文件 全球顶级功能无处不在。当然,如果你的代码开始变长,并且不同的机器人共享相同的功能,过一段时间之后,这会变得很痛苦。

    programming environment

    为了方便为多个bot编写代码,减少在裸JS中编写代码时出现意外错误的机会,并增加击败其他玩家的机会,我设置了 above TypeScript project 为我的每个机器人提供一个公共库和代码。当前目录结构看起来大致类似于以下内容:

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

    lib 是在Bot之间共享的通用代码,并为(非TS)Bot Land API提供类型脚本定义。然后,每个bot都有自己的文件夹,其中一个文件包含bot代码,另一个文件是样板文件 tsconfig.json :

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

    每次 tsconfig.json配置 它创建了一个 bot.js 包含从机器人本身以及 全部的 密码输入 common.js . 这种设置不太理想的原因有几个:它需要大量重复的样板文件,难以添加新的bot,为每个bot包含大量不必要的代码,并且要求每个bot单独构建。

    但是,基于 my research so far ,似乎没有一个简单的方法来做我想做的事。特别是,使用新的 tsc -b 选项和引用不起作用,因为这要求代码模块化,而Bot-Land需要一个单独的文件,其中包含在顶层定义的所有函数。

    尽可能多地实现以下目标的最佳方法是什么?

    • 不需要新的样板来添加新的bot(例如不需要 tsconfig.json配置 每个机器人)
    • 使用 import 为了避免输出未使用的代码,但是。。。
    • 仍然以Bot Land的特定格式将所有函数作为一个文件输出
    • 一个生成多个输出文件的构建步骤,每个bot一个
    • 好处:将构建过程与VS代码集成。目前有一个相应的样板 tasks.json 用于构建每个子项目。

    我模模糊糊地猜测答案可能除了咕噜声之外,还包括一些类似咕噜声的东西 tsc ,但我还不太清楚。

    0 回复  |  直到 6 年前
        1
  •  2
  •   PopGoesTheWza    6 年前

    这是我的 attempt 来满足你的要求。

    值得注意的文件:

    • src/tsconfig-botland.json 保留任何 bot.土地 脚本(包括我移到的自定义声明 types/bot-land/index.d.ts ). 你可以换哪个 strict 我使用的设置。
    • src/tsconfig.json 保存对所有机器人的引用。这是每当您想添加另一个bot脚本时要编辑的文件

    bot脚本至少是两个文件:极简 tsconfig.json 一个或多个 .ts 脚本文件。

    例如 src/AggroMiner/tsconfig.json :

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

    在大多数情况下,要启动新的bot脚本,您应该:

    1. 复制任何bot文件夹(即。 src/AggroMiner )到下的新文件夹 src
    2. 编辑 src/<newBotFolder>/tsconfig.json 编辑 outFile 以你的机器人的名字
    3. 编辑 src/tsconfig.json格式 并添加对 src/<newBotFolder>

    以下 npm / yarn 脚本已设置:

    • build 构建所有机器人
    • build-clean 它清除了 建造 运行之前的文件夹 建造
    • format 更漂亮 .ts条 文件位于 src公司
    • lint 对所有bot脚本运行tslint检查

    现在满足您的需求:

    • 不需要添加新bot的新样板(例如,每个bot不需要tsconfig.json)

    要实现这一点,需要创建一些脚本来枚举您的bots文件夹/脚本。。。并为每个机器人设置相关的 tsconfig.json配置 然后跑 tsc . 除非严格必要,否则最小设置(如上所述)可能就足够了。

    • 对常用函数使用import以避免输出未使用的代码,但是。。。

    首先,请注意,如果开始使用任何模块 export / import 语句中,您将需要额外的第三方来打包/刷新,以便实现单个文件输出。从我收集的Bot.land来看,您的脚本正在服务器上运行。除非死代码对你的机器人性能有影响,否则我不会真的去麻烦你。

    • 仍然以Bot Land的特定格式将所有函数作为一个文件输出

    完成。

    • 一个生成多个输出文件的构建步骤,每个bot一个

    完成。

    • 好处:将构建过程与VS代码集成。目前有一个对应的样板tasks.json用于构建每个子项目。

    这个 净现值 脚本应该出现在vsc的任务列表中(至少在我的任务列表中),因此 tasks.json 没必要。

        2
  •  3
  •   jperl    6 年前

    repo (重新git克隆它)

    实际上可以使用项目引用。按照以下步骤获得与原始文件相同的结果,所有函数都位于一个文件的顶层。但是,我找不到只在bots中导入所需函数的解决方案。也就是说,不用进出口。

    在您的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、movement.ts和utils.ts进行一些调整,这样ts就不会因为编译错误而困扰我们。

    数据.ts

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

    运动.ts

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

    实用工具

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

    接下来,我们在根目录中添加base.json(bots的tsconfig.json将对其进行扩展)。

    基.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