일반 종속성이있는 TypeScript 프로젝트를 구성하여 여러 일반 JavaScript 출력 파일을 빌드하십시오.


10

나는 현재 Bot Land스크립트 를 작성 하고 있습니다. Bot Land는 마우스와 키보드로 장치를 제어하는 ​​대신 API를 통해 봇을 제어하는 ​​코드를 작성한 다음 봇이 다른 사람의 봇과 싸울 수있는 실시간 전략 게임입니다. SC2의 장치에 익숙한 경우 깜박임 추적기, 공성 탱크, 의료진 및 울트라 리스크와 유사한 봇을 만들 수 있습니다. (소프트웨어 엔지니어에게는 재미있는 게임이지만이 질문의 범위를 벗어납니다.)

봇 랜드

봇 제어는 기본 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가 아닌) Bot Land API에 대한 TypeScript 정의를 제공합니다. 각 봇은 봇 코드를 포함하는 파일 하나와 다른 상용구가있는 자체 폴더를 가져옵니다 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 코드와 통합 현재 tasks.json각 하위 프로젝트를 구축하기위한 상용구 가 있습니다.

나는 그 대답에 아마도 Grunt와 같은 것이 포함되어 있다고 모호하게 추측 tsc하지만 확실하게 알 수는 없습니다.


모든 봇에 별도의 폴더가 있어야합니까? 아니면 각 봇이 단일 파일의 루트 레벨에있는 것으로 충분합니까? (예 <root>/MissileKite.ts)
a1300

1
변환 된 모든 봇 파일의 이름을 지정해야 bot.js합니까?
1300

단일 파일의 루트가 바람직합니다. 별도로 인해 별도의 폴더에 tsconfig.json있습니다. 변환 된 봇 파일의 이름은 원본 파일의 .js 버전으로 지정할 수 있습니다. 지금 repo 출력 에서이 방법으로 설정했습니다 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.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-cleanbuild실행하기 전에 폴더 를 지우십시오 .build
  • format.ts아래의 모든 파일에서 Prettier를 실행하려면src
  • lint 모든 봇 스크립트에서 tslint 검사를 실행하려면

이제 요구 사항을 충족시킵니다.

  • 새로운 봇을 추가하기 위해 새로운 상용구가 필요하지 않습니다 (예 : 봇당 tsconfig.json 없음)

이를 위해서는 봇 폴더 / 스크립트를 열거하는 스크립트를 작성하고 봇마다 관련을 설정 tsconfig.json하고 실행해야 tsc합니다. 꼭 필요한 경우가 아니면 최소 설정 (위 설명)으로 충분할 수 있습니다.

  • 사용하지 않는 코드를 출력하지 않으려면 공통 함수에 가져 오기를 사용하십시오.

먼저, 모듈 export/ import문을 사용하기 시작하면 단일 파일 출력을 달성하기 위해 추가 타사를 포장 / 트리 쉐이킹해야합니다. 내가 Bot.land에서 수집 한 것부터 스크립트가 서버에서 실행되고 있습니다. 데드 코드가 봇 성능에 영향을 미치지 않는 한 실제로 귀찮게하지는 않습니다.

  • Bot Land의 특정 형식으로 모든 기능을 단일 파일로 출력

끝난.

  • 봇당 하나씩 여러 개의 출력 파일을 생성하는 단일 빌드 단계

끝난.

  • 보너스 : 빌드 프로세스를 VS 코드와 통합 각 하위 프로젝트를 빌드하기 위해 현재 이에 상응하는 상용구 작업이 있습니다.

npm스크립트 VSC의 작업 목록에 나타납니다 따라서 만들기 (적어도 그들은 내에서 할) tasks.json필요합니다.


데드 코드는 여기에서 만든 다른 모든 것에 대한 훌륭한 타협입니다. types/bot-land정의에 사용한 이유와 strict설정 을 선택한 이유 를 알려주시겠습니까 ?
Andrew Mao

Types / bot-land / index.d.ts는 실제로 lib의 원래 .d.ts이며 이름이 바뀌고 다르게 배치됩니다. 모든 스크립트에 대한 일반적인 bot.land 실행 컨텍스트를 설명한다고 가정하므로 모든 봇 스크립트에서 항상 사용할 수 있는지 확인하십시오. '엄격한'설정은 선호하는 설정을 게으르게 복사했기 때문에 여기에만 있습니다 (예쁜 설정과 동일). 그것들은 사용자 (사용자) 환경 설정에 맞게 조정되어야합니다.
PopGoesTheWza

나는 그것을 넣을 관습적인 이유가 types있는지 또는 그것이 당신이 선택한 것을 구성하는 특별한 방법 인지 궁금합니다 .
Andrew Mao

유일한 이유는 그것이 bot.land 컨텍스트라고 가정하기 때문입니다. 당신의 nodejs 스크립트에서 이미 사용할 수 @ 유형 / 노드 typings을 가진 것처럼 생각
PopGoesTheWza

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"
  ]
}

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

그래서 나는 이와 같은 것을 생각했지만 그것이 작동하지 않는 이유는 브랜치에서 출력되는 파일이 맨 위에 이와 같은 많은 것들을 가지고 있고 게임에는 모든 기능을 가진 하나의 파일이 필요하기 때문입니다. 따라서 파일을 붙여 넣는 대신 복사 할 파일을 만들기 위해 컴파일 된 모든 출력을 수동으로 결합해야합니다. ` "엄격한 사용"; 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.