การใช้โมดูลใน Meteor.js ด้วย Typescript
ทุกคน ผมกำลังพยายามทำสิ่งที่คิดว่าควรง่าย แต่ต้องมีบางอย่างที่ผมทำผิด ผมกำลังพยายามเพียงแค่มีโครงสร้างที่ชัดเจนในแอปพลิเคชัน Meteor ของผมที่ใช้ Typescript
นี่คือข้อกำหนดของฉัน:
- อินเทอร์เฟซทั้งหมดสามารถใช้งานได้ทั้งในฝั่งไคลเอนต์และเซิร์ฟเวอร์
- การใช้งานคลาสบางอย่างมีให้เฉพาะบนเซิร์ฟเวอร์เท่านั้น
- ฉันไม่ต้องการพึ่งลำดับการโหลดไฟล์เพื่อให้แอปพลิเคชันของฉันทำงานได้อย่างถูกต้อง
- ฉันต้องการโมดูลของตัวเองเพื่อไม่ให้ชนกับวัตถุทั่วโลก (เช่นคลาส Position เป็นตัวอย่าง)
- ฉันต้องการมีไฟล์ include แบบโมโนลิธิกหนึ่งไฟล์สำหรับเซิร์ฟเวอร์ หนึ่งไฟล์สำหรับทั้งไคลเอนต์และเซิร์ฟเวอร์ และหนึ่งไฟล์สำหรับไคลเอนต์ (ไม่อยากมี include หลายสิบไฟล์อยู่ด้านบนของไฟล์ของฉัน)
การตั้งค่าที่ฉันมีอยู่ตอนนี้คือแบบนี้
เซิร์ฟเวอร์
- เซิร์ฟเวอร์-หนังสือ.ts
ที่ใช้ร่วมกัน
- collections.ts
คำนิยาม
เซิร์ฟเวอร์
- include.d.ts (รวมไฟล์ .d.ts ทั้งหมดในโฟลเดอร์นี้)
ที่ใช้ร่วมกัน
- include.d.ts (รวมไฟล์ .d.ts ทั้งหมดที่นี่)
ในแต่ละไฟล์ .d.ts ที่ฉันมี
module MyModule {
interface Bla {}
};
ในแต่ละไฟล์ .ts ที่กำหนดคลาส ฉันมี:
module MyModule {
export class MyBla implements Bla {};
}
ไฟล์ .d.ts ทั้งหมดที่สร้างขึ้นสำหรับคลาสจะถูกสร้างโดย tsc -d
ไม่มีไฟล์ .ts ใดถูกรวมผ่าน ///<reference> แต่มีเพียงไฟล์ .d.ts เท่านั้น
ตอนนี้ เมื่อฉันเรียกใช้นี้ ฉันได้รับข้อผิดพลาดว่า MyModule ไม่ถูกกำหนด:
/// <reference path="shared/include.d.ts"/>
/// <reference path="server/include.d.ts"/>
Meteor.startup(() => {
var temp = new MyModule.ServerBook();
});
ข้อผิดพลาดเกิดขึ้นตรงที่ MyModule
ฉันทำอะไรผิดหรือ? ควรตั้งค่าอย่างไรให้ถูกต้องที่นี่?
ขอบคุณ!
คำตอบ #1
ฉันได้จัดการกับปัญหานี้ในบล็อกของฉันแล้ว ฉันตัดสินใจที่จะใช้คำสั่งที่ชั่วร้าย eval เนื่องจากมันให้ความเป็นไปได้ที่ง่ายที่สุดในการใช้โมดูลจนกว่าจะมีบางสิ่งที่ซับซ้อนมากขึ้นปรากฏขึ้น
ไฟล์ /lib/foo.ts อยู่ในไดเรกทอรีย่อยเนื่องจากต้องถูกโหลดก่อน Bar
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Foo {
foo():string {
return 'foo'
}
}
}
ไฟล์ /bar.ts
/// <reference path="lib/foo.ts"/>
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Bar extends Foo {
bar () : string {
return 'bar';
}
}
}
ไฟล์ /test.ts
/// <reference path="lib/foo.ts"/>
/// <reference path="bar.ts"/>
var m = new Hugo.Bar();
console.log(m.bar());
console.log(m.foo());
ดังที่กล่าวไว้ที่นี่ สำหรับชั้นเรียน วิธีแก้ปัญหาก็ง่ายกว่านี้อีก:
class ExportedClass {
variable : int;
}
this.ExportedClass = ExportedClass;
คำตอบ #2
ไฟล์คำจำกัดความควรใช้คำสำคัญ declare โดยปกติคุณจะได้รับข้อผิดพลาดหากคุณไม่ได้ใช้คำสำคัญนี้
declare module MyModule {
export interface Bla {}
}
และ
declare module MyModule {
export class MyBla implements Bla {
}
}
นอกจากนี้ยังควรตรวจสอบด้วยว่าคลาส ServerBook มีคำสำคัญ export หรือไม่ (เหมือนกับ MyBla ในตัวอย่างของคุณ)
