2012-10-07 37 views
10

Tôi đã hoàn thành việc chuyển một thư viện JavaScript sang TypeScript trong Visual Studio 2012. Tất cả trong tất cả khoảng 60 lớp, với mỗi lớp được định nghĩa trong tệp .ts của riêng nó.TypeScript: Nhiều dự án trong giải pháp

Tất cả các lớp được định nghĩa trong cùng một mô-đun. Tôi sử dụng các chú thích tham chiếu để làm lại các lớp được định nghĩa trong các tệp khác. Bố cục của mỗi tệp trông giống như sau:

///<reference path='./../myotherclass.ts' /> 

module MyModule { 

    export class MyClass { 
     ... 
    } 

} 

Bây giờ tôi đã tạo một dự án thứ hai trong cùng một giải pháp sẽ là ứng dụng thực tế sử dụng thư viện mới được chuyển. Tôi phải bao gồm thư viện của tôi bằng cách nào đó và tôi đoán đó là những gì hệ thống mô-đun cho. Tuy nhiên, tôi không chắc chắn những gì (các) tệp để nhập như MyModule được trải rộng trên hàng tá tệp. Đây có phải là những gì tôi có thể sử dụng tệp .d.ts không?

Ngoài ra, để có thể nhập mô-đun, nó phải được khai báo bằng từ khóa 'xuất' nhưng nếu tôi làm điều đó thì không tìm thấy nhận xét tham chiếu nữa.

Trên hết, cả hai dự án phải được biên dịch sao cho đầu ra trình biên dịch có thể dễ dàng được sử dụng với bộ nạp mô-đun như requireJS.

Cách tiếp cận tốt nhất để thực hiện tất cả điều này là gì?

Cảm ơn bạn!

Trả lời

9

Ok, vì vậy hãy để tôi bắt đầu bằng cách nói rằng "Mô-đun" có thể có nghĩa là những thứ khác nhau. Ví dụ, có "mô-đun mô-đun" là những gì mà "MyModule" của bạn tạo ra. Theo như tôi thu thập, TypeScript đề cập đến những điều này là "Mô-đun nội bộ" trong thông số ngôn ngữ, và chúng khác với "Mô-đun bên ngoài" mà bạn sẽ tải bằng thứ gì đó như RequireJS. Sự khác biệt chính là các mô-đun bên ngoài mong muốn có môi trường riêng biệt của chúng với một đối tượng 'xuất khẩu' được xác định trước mà chúng có thể sử dụng để xuất khẩu chức năng của chúng.

Hãy xem tại đầu ra của mô-đun của bạn:

var MyModule; 
(function (MyModule) { 
    var MyClass = (function() { 
     function MyClass() { } 
     return MyClass; 
    })(); 
    MyModule.MyClass = MyClass;  
})(MyModule || (MyModule = {})); 

Bạn thấy rằng nó được xuất khẩu điều vào "MyModule" mà sẽ được cung cấp trên toàn cầu để kịch bản khác tập tin bạn tải với, ví dụ, một khối html "script". Là bạn đã đề cập bạn có 60 trong số này, bạn có thể cũng có thể thiết lập trình biên dịch để xuất ra một tệp duy nhất mà bạn có thể bao gồm trong đánh dấu, thay vì tải từng tệp một.

Di chuyển trên, hãy nhìn vào những gì xảy ra với sản lượng nếu bạn thay đổi khai module của bạn từ "mô-đun MyModule {...}" thành "mô-đun xuất khẩu MyModule {...}":

(function (MyModule) { 
    var MyClass = (function() { 
     function MyClass() { } 
     return MyClass; 
    })(); 
    MyModule.MyClass = MyClass;  
})(exports.MyModule || (exports.MyModule = {})); 

Như bạn thấy, mô-đun của bạn vẫn đang sử dụng "mô-đun mô-đun" nhưng nó đang được gán làm thành viên của "xuất khẩu", biểu thị rằng nó có nghĩa là được tải, ví dụ, chức năng "yêu cầu" của nút.

Trong trường hợp này, bạn sẽ muốn thực sự sử dụng mô-đun của bạn với mã này:

import wrapper = module("./MyModule"); 
var instance = new wrapper.MyModule.MyClass(); 

Lưu ý "./MyModule" tên thực sự đề cập đến filename (trừ phần mở rộng .js) các module được định nghĩa trong (đây là lý do tại sao VS đã nói rằng nó không thể tìm thấy những mô-đun cho bạn).Mã nên biên dịch thành một cái gì đó như:

var wrapper = require("./MyModule"); 
var instance = new wrapper.MyModule.MyClass(); 

Để thêm vào điều này, bạn thậm chí không còn thực sự cần phải làm gì với từ khóa "mô-đun" để có mô-đun. Bạn có thể chỉ cần xuất hàm:

// foo.ts 
export function foo() { 
    ... 
}; 

// some other file in the same dir 
import wrapper = module("./foo"); 
var result = wrapper.foo(); 

Điều này hoạt động vì hàm 'foo' sẽ được gán trực tiếp cho "xuất" sẽ được đặt bí danh thành "trình bao bọc" trong tệp khác.

Để thêm vào mớ hỗn độn phức tạp của các mô-đun liên quan, tôi cũng nên đề cập đến các mô-đun AMD khác vì chúng được tải không đồng bộ, không giống như "yêu cầu" của nút. Để có được TypeScript để xuất ra những thứ bạn cần phải truyền vào một tham số "--module AMD" tới trình biên dịch.

Dù sao, tôi hy vọng tôi đã giải thích tình huống tốt đến mức bạn sẽ có thể tìm ra chính xác những gì bạn cần/muốn. Loại mô-đun bạn kết thúc bằng cách sử dụng sẽ thực sự phụ thuộc vào cách bạn sẽ sử dụng chúng ... tức là, nút, web hoặc một số kết hợp của cả hai.

+0

Cảm ơn bạn, điều này rất hữu ích. Cuối cùng tôi đã làm mà không có mô-đun bên ngoài sau khi tất cả: Tôi biên dịch các thư viện thành một tập tin .js lớn và ứng dụng vào một và chỉ đơn giản là tải chúng thông qua các thẻ script. Trong các tệp nguồn của ứng dụng, tôi sử dụng các chú thích tham chiếu tới tệp .d.ts của thư viện để làm cho các lớp của nó có sẵn. – vexator

+0

có cách nào để tải hai tệp vào một trình bao bọc không? Tôi xác định viewmodels ans xuất khẩu như các lớp học trong các tập tin loại của tôi. Sau đó, khi nhập khẩu tôi luôn luôn kết thúc làm nhập khẩu wrapper1 = module ("file1"), nhập khẩu wrapper2 = module ("file2"); và sau đó mới wrapper1.Viewmodel1() và new wrapper2.ViewModel2(). Sẽ được tốt đẹp nếu everyhing chỉ có thể dưới một mô-đun, viewmodels.Viewmodel1 và viewmodel.Viewmodel2. Để có được điều này tôi cần phải trưng ra tất cả các lớp xem moedl trong cùng một tệp, giới hạn tổng quan. –

+0

@ s093294 Đã vài tháng kể từ khi tôi xem xét bản ghi, vì vậy hãy ghi nhớ điều đó. Dù sao, sử dụng '/// ' ở trên cùng của 'file1.ts' và biên dịch với' tsc --out file.js file1.ts'. Trình biên dịch sẽ tự động nhận rằng 'file1.ts' yêu cầu' file2.ts' (nhờ tham chiếu) và biên dịch nó thành một tệp javascript duy nhất. Mặc dù không chính xác bản demo hoàn hảo cho bạn, hãy xem: https://github.com/nxn/ModuleDemo - cụ thể là các mô đun 'make.bat', 'Address' và 'Contacts' (được triển khai trên nhiều tệp), và 'default.htm', tải các tệp javascript đã biên dịch. – nxn

Các vấn đề liên quan