กำหนดค่าโครงการ TypeScript ด้วยการอ้างอิงทั่วไปเพื่อสร้างไฟล์เอาต์พุต JavaScript ธรรมดาหลายไฟล์


10

ฉันกำลังเขียนบางสคริปต์สำหรับBot ที่ดิน Bot Land เป็นเกมวางแผนแบบเรียลไทม์ที่แทนที่การควบคุมหน่วยของคุณด้วยเมาส์และแป้นพิมพ์คุณเขียนโค้ดเพื่อควบคุมบอทของคุณผ่าน API จากนั้นบอทของคุณจะต่อสู้กับบ็อตของผู้อื่น หากคุณคุ้นเคยกับหน่วยใน SC2 คุณสามารถสร้างบอทที่คล้ายกับกะพริบ stalkers, รถถังโจมตี, medics และ ultralisks (มันเป็นเกมที่สนุกสำหรับวิศวกรซอฟต์แวร์ แต่อยู่นอกขอบเขตของคำถามนี้)

ที่ดินบอท

การควบคุม Bot มีสามระดับของความซับซ้อนที่เพิ่มขึ้น: AI เริ่มต้น, ภาษาการเขียนโปรแกรมแบบScratch -like และชุด 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 สำหรับ Bot Land API (ไม่ใช่ TS) บอทแต่ละตัวจะได้รับโฟลเดอร์ของตัวเองโดยมีไฟล์หนึ่งไฟล์ที่มีรหัสบอทและอีกหนึ่งไฟล์สำเร็จรูป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 ต้องการไฟล์เดียวที่มีฟังก์ชั่นทั้งหมดที่กำหนดไว้ที่ระดับบนสุด

อะไรคือวิธีที่ดีที่สุดในการบรรลุสิ่งต่อไปนี้ให้ได้มากที่สุด

  • ไม่จำเป็นต้องมี boilerplate ใหม่ในการเพิ่ม bot ใหม่ (เช่น no tsconfig.jsonต่อ bot)
  • ใช้importสำหรับฟังก์ชั่นทั่วไปเพื่อหลีกเลี่ยงการส่งออกรหัสที่ไม่ได้ใช้ แต่แล้ว ...
  • ยังคงเอาท์พุทฟังก์ชั่นทั้งหมดเป็นไฟล์เดียวในรูปแบบเฉพาะของ Bot Land
  • ขั้นตอนการบิลด์เดียวที่สร้างไฟล์เอาต์พุตหลายไฟล์หนึ่งไฟล์สำหรับแต่ละบ็อต
  • โบนัส: การรวมกระบวนการสร้างเข้ากับ VS Code ขณะนี้มีสำเร็จรูปtasks.jsonสำหรับการสร้างแต่ละโครงการย่อย

ฉันคาดเดาไม่ชัดเจนว่าคำตอบอาจเกี่ยวข้องกับเรื่อง Grunt นอกเหนือไปจากนี้tscแต่ฉันไม่รู้เกี่ยวกับเรื่องนั้นอย่างแน่นอน


จำเป็นหรือไม่ที่บอตทั้งหมดมีโฟลเดอร์แยกกัน? หรือมันก็เพียงพอแล้วที่บอทแต่ละตัวอยู่ในระดับรูทในไฟล์เดียว? (เช่น<root>/MissileKite.ts)
a1300

1
ไฟล์ bot transpiled ทั้งหมดจะต้องตั้งชื่อbot.jsหรือไม่?
a1300

รูตในไฟล์เดียวน่าจะดีกว่า tsconfig.jsonพวกเขาอยู่ในโฟลเดอร์ที่แยกจากกันเพราะการแยกจากกัน ไฟล์ ธ ปท. ที่ transpiled สามารถตั้งชื่ออะไรก็ได้โดยเฉพาะอย่างยิ่งไฟล์ต้นฉบับ. js ฉันมีมันติดตั้งด้วยวิธีนี้ในขณะนี้ใน outputting repo build/MissileKite.jsไป
Andrew เหมา

1
@ andrew-mao คุณสามารถดูเทมเพลตของฉันสำหรับโครงการ GAS ที่ตอบสนองความต้องการส่วนใหญ่ของคุณ (แต่กำหนดเป้าหมายสภาพแวดล้อมที่แตกต่างกัน) ถ้ามันเหมาะกับคุณฉันอาจจะปรับตัวให้เข้ากับคุณในบางสัปดาห์หน้า github.com/PopGoesTheWza/ts-gas-project-starter
PopGoesTheWza

เป็นtsconfig-gas.jsonสิ่งที่เกี่ยวข้องเพื่อดูที่นั่น?
Andrew เหมา

คำตอบ:


2

นี่คือความพยายามของฉันที่จะตอบสนองความต้องการของคุณ

ไฟล์เด่น:

  • src/tsconfig-botland.jsonเก็บการตั้งค่าสำหรับสคริปต์bot.landใด ๆ(รวมถึงการประกาศที่คุณกำหนดเองซึ่งฉันย้ายไปtypes/bot-land/index.d.ts) คุณสามารถเปลี่ยนการstrictตั้งค่าที่ฉันใช้
  • src/tsconfig.jsonถือการอ้างอิงถึงบอททั้งหมดของคุณ นี่คือไฟล์ที่จะแก้ไขทุกครั้งที่คุณต้องการเพิ่มสคริปต์ bot อื่น

สคริปต์ ธ ปท. เป็นไฟล์อย่างน้อยสองไฟล์: ไฟล์ minimalist 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ซึ่งล้างbuildโฟลเดอร์ก่อนใช้งานbuild
  • formatเพื่อเรียกใช้ Prettier ใน.tsไฟล์ทั้งหมดภายใต้src
  • lint เพื่อรันการตรวจสอบ tslint กับสคริปต์ bot ทั้งหมด

ตอนนี้ใช้ความต้องการของคุณ:

  • ไม่จำเป็นต้องมี boiler สำเร็จรูปใหม่ในการเพิ่ม bot ใหม่ (เช่นไม่มี tsconfig.json ต่อ bot)

เพื่อให้บรรลุนี้จะต้องมีการสร้างสคริปต์ซึ่งจะระบุบอทโฟลเดอร์ / สคริปต์ ... และการติดตั้งที่เกี่ยวข้องต่อ ธ ปทและเรียกใช้tsconfig.json tscการตั้งค่าขั้นต่ำ (อธิบายข้างต้น) อาจเพียงพอ

  • ใช้การนำเข้าสำหรับฟังก์ชั่นทั่วไปเพื่อหลีกเลี่ยงการส่งออกรหัสที่ไม่ได้ใช้ แต่แล้ว ...

ก่อนอื่นให้ระวังว่าถ้าคุณเริ่มใช้โมดูลexport/ importคำสั่งใด ๆคุณจะต้องมีบุคคลที่สามเพิ่มเติมในการแพ็ค / treeshake เพื่อให้ได้ผลลัพธ์ไฟล์เดียว จากสิ่งที่ฉันสามารถรวบรวมของ Bot.land สคริปต์ของคุณทำงานบนเซิร์ฟเวอร์ เว้นแต่เดดโค้ดจะมีผลกระทบต่อประสิทธิภาพการทำงานของบอทของคุณฉันก็คงไม่สนใจอะไร

  • ยังคงเอาท์พุทฟังก์ชั่นทั้งหมดเป็นไฟล์เดียวในรูปแบบเฉพาะของ Bot Land

เสร็จสิ้น

  • ขั้นตอนการบิลด์เดียวที่สร้างไฟล์เอาต์พุตหลายไฟล์หนึ่งไฟล์สำหรับแต่ละบ็อต

เสร็จสิ้น

  • โบนัส: การรวมกระบวนการสร้างเข้ากับ VS Code ขณะนี้มีงานสร้างแผ่นสำเร็จรูปสำเร็จรูปที่สอดคล้องกันสำหรับการสร้างแต่ละโครงการย่อย

npmสคริปต์ควรจะปรากฏใน VSC ของรายการงาน (อย่างน้อยพวกเขาทำในเหมือง) จึงทำให้tasks.jsonไม่จำเป็น


Deadcode เป็นสิ่งที่ดีสำหรับทุกสิ่งที่คุณทำที่นี่ คุณแจ้งให้เราทราบได้ไหมว่าทำไมคุณถึงใช้types/bot-landคำจำกัดความและทำไมคุณถึงเลือกstrictการตั้งค่า
Andrew Mao

ประเภท / bot-land / index.d.ts จริงๆคือ. d.ts ดั้งเดิมของคุณจาก lib เปลี่ยนชื่อและวางแตกต่างกัน Îสมมติว่าเป็นประเภทของการอธิบายบริบทการดำเนินการทั่วไป bot.land สำหรับสคริปต์ทั้งหมดและทำให้ฉันแน่ใจว่าจะใช้ได้เสมอในสคริปต์ ธ ปท. การตั้งค่า 'เข้มงวด' อยู่ที่นี่เพียงเพราะฉันคัดลอกการตั้งค่าที่ชื่นชอบของฉันอย่างเกียจคร้าน (เช่นเดียวกับการตั้งค่าที่สวยกว่า) สิ่งเหล่านั้นควรปรับให้เข้ากับการตั้งค่าของผู้ใช้ (คุณ)
PopGoesTheWza

ฉันแค่สงสัยว่ามีเหตุผลตามธรรมเนียมที่จะนำสิ่งนั้นเข้ามาtypesหรือว่าเป็นเพียงวิธีการเฉพาะในการจัดระเบียบที่คุณเลือก
Andrew เหมา

เหตุผลเดียวคือสมมติว่าเป็นบริบท bot.land คิดว่ามันเหมือนกับการมีการพิมพ์ @ types / node ที่มีอยู่แล้วในสคริปต์ nodejs ของคุณ
PopGoesTheWza

1
โฟลเดอร์ A / types เป็นหนึ่งในสถานที่ทั่วไปที่มีการประกาศประเภทภายนอก (เช่นบริบทการดำเนินการเฉพาะเช่นบ็อตเอ็นจิ้นหรือโมดูล / แพ็คเกจ 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, Movement.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

ดังนั้นฉันจึงคิดบางอย่างเช่นนี้ แต่สาเหตุที่ใช้ไม่ได้เพราะไฟล์ที่ได้รับจากสาขาของคุณมีสิ่งต่าง ๆ ที่ด้านบนสุดและเกมต้องการหนึ่งไฟล์ที่มีฟังก์ชั่นทั้งหมดในนั้น ดังนั้นฉันจะต้องเอาก้อนหินที่รวบรวมได้ทั้งหมดออกด้วยกันเพื่อสร้างไฟล์ที่ฉันจะอัปโหลดแทนที่จะคัดลอกวางไฟล์ `" ใช้อย่างเข้มงวด "; การส่งออก. _ esModule = จริง; var data_1 = ต้องการ ("../ lib / data"); var Movement_1 = ต้องการ ("../ lib / การเคลื่อนไหว"); var utils_1 = ต้องการ ("../ lib / utils"); `
Andrew Mao

แต่ใช้งานได้เนื่องจาก lib ยังเอาต์พุต (บิวด์) ในโฟลเดอร์บิลด์ (ด้วยการอ้างอิง)
jperl

ฉันอยู่ในขั้นตอนการแก้ไขความคิดเห็นของฉัน - ดูด้านบน หรือดูที่build/MissileKite.jsเอาท์พุทเมื่อคุณสร้าง repo เดิม
Andrew เหมา

@AndrewMao ขออภัยเฉพาะตอนนี้ฉันเข้าใจสิ่งที่คุณหมายถึง "เพราะต้องใช้รหัสที่จะทำให้เป็นโมดูลและ Bot Land ต้องใช้ไฟล์เดียวที่มีฟังก์ชั่นทั้งหมดที่กำหนดไว้ที่ระดับบนสุด" ฉันคิดเกี่ยวกับการใช้ "prepend: true" แต่ต้องใช้ outFile และ ts จะไม่ให้เรารวบรวมไฟล์ใน lib เพราะบางคนขึ้นอยู่กับคนอื่น
jperl

@AndrewMao ฉันได้เพิ่มการสนับสนุน Webpack ฉันแก้ไขโพสต์และผลักดันการเปลี่ยนแปลงใน repo แจ้งให้เราทราบหากดีกว่า
jperl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.