การใช้ module() และ AMD ใน Typescript ส่งผลให้โค้ดไม่สามารถแชร์ได้
สถานการณ์ที่ 1:
ฉันมีโปรเจกต์ที่มีไฟล์ Typescript 2 ไฟล์ที่ดูเหมือนแบบนี้:
// file:/app/Dogs/Beagle.ts
export module Dogs {
export Class Beagle {
public Bark() {
document.write('Woof');
}
}
}
// file:/app/DogPage.ts
import m = module('./Dogs/Beagle');
var b = new m.Dogs.Beagle();
b.Bark();
// file:/config.ts
var require: {baseUrl: '/app'};
สิ่งเหล่านี้คอมไพล์ได้โดยไม่มีปัญหา ผมยังใช้ RequireJS ในการโหลดไฟล์บนหน้าเว็บ Dogs.html ของผม โดยใช้โค้ด HTML ดังนี้:
<script src="/app/config.js" type="text/javascript"></script>
<script data-main="DogPage" src="lib/require.js" type="text/javascript"></script>
อีกครั้ง นี่ใช้ได้ดีและการใช้งานวัตถุ Beagle ของฉันส่งผลให้มีคำว่า "Woof" บนหน้าเว็บ
สถานการณ์ที่ 2 (ซึ่งปัญหาของฉันเกิดขึ้น)
ตอนนี้ฉันมีโปรเจกต์ที่สองที่ฉันต้องการใช้ Beagle.ts แต่ฉันไม่อยากแค่คัดลอกไฟล์ ts ดังนั้นฉันจึงสร้างสำเนาทั่วไปในโปรเจกต์ที่สามที่ฉันต้องการใช้จากโปรเจกต์ 1 และ 2
ดังนั้นไฟล์ของฉันจะมีลักษณะเช่นนี้ในเวลาพัฒนา:
/project1
/Dogs.html
/DogPage.ts
/project2
/MoreDogs.html
/MoreDogsPage.ts
/project3
/app
/Beagle.ts
และฉันวางแผนที่จะคัดลอกโฟลเดอร์ app ของ Project3 ในเวลาที่ปรับใช้เพื่อให้โครงสร้างดูเหมือนนี้:
/project1
/Dogs.html
/DogPage.ts
/app
/Beagle.ts
ตอนนี้ฉันจะเชื่อมต่อ Beagle.ts เข้ากับแอป 2 ตัวของฉันได้อย่างไร เพื่อให้ฉันสามารถคอมไพล์มันได้ในช่วงพัฒนาระบบ และยังให้เส้นทางทำงานได้ในโปรดักชันตามที่อธิบายไว้? เส้นทางตามที่ระบุข้างต้นจะทำงานได้ตอนรันไทม์ แต่ฉันไม่สามารถคอมไพล์โค้ดในช่วงพัฒนาระบบได้
ถ้าฉันทำแบบนี้:
import m = module('../../../Dogs/Beagle');
แน่นอนว่ามันสมมติว่ามีตำแหน่งสัมพัทธ์บนฮาร์ดไดรฟ์ของฉันในช่วงเวลาการพัฒนา และจะไม่มีทางทำงานในสภาพแวดล้อมจริง
ดูเหมือนว่าฉันติดอยู่และต้องเก็บสำเนาของโค้ดไว้ทั้งสองโปรเจกต์ อาจไม่ใช่เรื่องใหญ่สำหรับตัวอย่างที่สร้างขึ้นนี้ แต่โปรเจกต์จริงของฉันมีไฟล์คลาสที่นำกลับมาใช้ซ้ำได้หลายสิบไฟล์ ฉันจะจัดการความยุ่งเหยิงนี้อย่างไรและยังทำให้มันคอมไพล์ได้?
อัปเดต: ข้อเสนอของ BASarat เกี่ยวกับ VS "ไฟล์ที่เชื่อมโยง" ส่งผลให้เกิดสิ่งนี้:
/*
Compile Error.
See error list for details
C:\proj2\app\MoreDogs.ts(2,34) : Incorrect reference: imported file: "./Dogs/Beagle" cannot be resolved.
C:/proj2/app/MoreDogs.ts(2,18): The name ''./Dogs/Beagle'' does not exist in the current scope
C:/proj2/app/MoreDogs.ts(2,18): A module cannot be aliased to a non-module type
C:/proj2/app/MoreDogs.ts(5,12): Expected var, class, interface, or module
*/
ถ้านักพัฒนากำลังใช้ Visual Studio (ซึ่งเป็นข้อสมมติที่ผม/ดิฉันค่อนข้างไม่อยากทำ) สิ่งนี้จะสร้างภาพลวงตาของฐานรหัสที่เป็นเอกภาพจากมุมมองของ Solution Explorer แต่ TypeScript จะไม่คอมไพล์โดยใช้ความเข้าใจเกี่ยวกับฐานรหัสของ Solution Explorer ดังนั้นการคอมไพล์จึงล้มเหลวจริง ๆ ผม/ดิฉันพลาดอะไรไปหรือเปล่า?
คำตอบ #1
คุณควรพิจารณาวิธีการของคุณใหม่ คุณกำลังพัฒนาห้องสมุด ดังนั้นคุณควรปฏิบัติต่อมันในลักษณะนั้น การพยายามอ้างอิงซอร์สโค้ดของทรัพยากรที่ใช้ร่วมกันไม่ใช่วิธีแก้ปัญหาที่ฉันจะแนะนำ ยิ่งไปกว่านั้นคุณก็ได้พบปัญหาเมื่อลองแก้ไขด้วยวิธีนี้แล้ว
ดังนั้น คำแนะนำของฉันคือให้พิจารณาโปรเจกต์ที่แชร์ของคุณราวกับว่ามันเป็นไลบรารีภายนอก เช่น jQuery คุณควรพิจารณาการรวม ผลลัพธ์ ของโปรเจกต์ที่แชร์เป็นส่วนประกอบของโปรเจกต์อื่น ๆ แทนที่จะอ้างอิงไปยังซอร์สโดยตรง
แล้วคุณจะทำสิ่งนี้ และ ใช้ TypeScript ต่อไปได้อย่างไร? คุณสามารถจัดทำไฟล์คำจำกัดความสำหรับไลบรารีที่ใช้ร่วมกันของคุณซึ่งมีคำจำกัดความทั้งหมดให้กับโปรเจกต์ที่ใช้มัน จากนั้นเรียกใช้ผลลัพธ์ของไลบรารีที่ใช้ร่วมกันในบางจุดของจุดเริ่มต้นแอปของคุณเพื่อให้แน่ใจว่าสามารถอ้างอิงโมดูลเหล่านั้นได้ สุดท้ายให้ใช้คำสั่ง require("module_name") เพื่อรวมโมดูลเหล่านั้นในที่ที่คุณต้องการ
คำตอบของคำถามนี้ใช้วิธีเดียวกับที่ฉันอธิบายข้างต้น อย่างไรก็ตาม ฉันไม่ได้ทำเครื่องหมายคำถามของคุณว่าเป็นคำถามซ้ำแบบตรงๆ แต่แนวคิดนั้นชัดเจนว่าเหมือนกัน
คำตอบ #2
เพิ่ม «ลิงก์ไปยังไฟล์ภายนอก» ให้กับทั้งสองโครงการ
http://www.basarat.com/2013/05/add-existing-item-as-link-in-visual.html