2012-10-07 13 views
10

Zakończyłem przenoszenie biblioteki JavaScript do TypeScript w Visual Studio 2012. W sumie około 60 klas, z każdą klasą zdefiniowaną w osobnym pliku .ts.TypeScript: Wiele projektów w roztworze

Wszystkie klasy są zdefiniowane w tym samym module. Używam odwołań do odwołań do klas zdefiniowanych w innych plikach. Układ każdego pliku wygląda następująco:

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

module MyModule { 

    export class MyClass { 
     ... 
    } 

} 

Teraz stworzyliśmy drugi projekt w tym samym roztworze, który będzie rzeczywistą aplikacji przy użyciu mojego nowo przeportowany bibliotekę. Muszę jakoś włączyć moją bibliotekę i myślę, że właśnie do tego służy system modułowy. Jednak nie jestem pewien, jakie pliki zaimportować, ponieważ MyModule jest rozrzucony na dziesiątkach plików. Czy do tego mogę użyć pliku .d.ts?

Ponadto, aby móc importować moduł, musi on zostać zadeklarowany za pomocą słowa kluczowego "export", ale jeśli to zrobię, to nie zostanie znaleziony przez komentarze referencyjne.

Co więcej, oba projekty powinny zostać skompilowane w taki sposób, aby wyjście kompilatora było łatwe do użycia z modułem ładowania modułów jak requireJS.

Jakie jest najlepsze podejście do realizacji tego wszystkiego?

Dziękujemy!

Odpowiedz

9

OK, więc zacznę od stwierdzenia, że ​​"Moduł" może oznaczać różne rzeczy. Na przykład istnieje "wzorzec modułu", który tworzy "Mój moduł". O ile wiem, TypeScript nazywa je "modułami wewnętrznymi" w specyfikacji językowej, a różnią się one od "External Modules", które ładowałbyś z czymś takim jak RequireJS. Główne rozróżnienie polega na tym, że moduły zewnętrzne oczekują własnego izolowanego środowiska z predefiniowanym obiektem "eksportu", którego mogą użyć do eksportowania swoich funkcji.

Spójrz na wyjściu modułu:

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

widać, że eksportuje rzeczy do „mymodule”, który zostanie udostępniony globalnie do innego skryptu plików załadować z, na przykład, blok "skryptu" html. Ponieważ wspomniano o 60 z nich, prawdopodobnie można również ustawić kompilator tak, aby wysyłał pojedynczy plik, który można uwzględnić w znacznikach, zamiast ładować każdy plik jeden po drugim.

Idąc dalej, spójrz na to, co dzieje się na wyjściu jeśli zmienisz swoją deklarację z modułu "moduł mymodule {...}" do "modułu eksportu mymodule {...}":

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

Jak widać, twój moduł nadal używa "wzorca modułu", ale jest on przypisywany jako członek "eksportu", co oznacza, że ​​ma być załadowany, na przykład, funkcją węzła "wymagaj".

W tym przypadku, co chcesz rzeczywiście korzystać z modułu z tym kodem:

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

Uwaga „./MyModule” Nazwa rzeczywiście odnosi się do pliku (minus rozszerzeniem .js) moduł jest zdefiniowany w (dlatego VS mówił, że nie może znaleźć tych modułów dla ciebie).Kod powinien skompilować coś podobnego:

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

Aby dodać do tego, nie ma już nawet naprawdę trzeba zrobić coś z „modułem” słowo kluczowe aby mieć moduł. można po prostu wyeksportować funkcję:

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

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

To działa, ponieważ funkcja „foo” zostanie bezpośrednio przypisane do „eksportu”, która zostanie aliasem „wrapper” w innym pliku.

Aby dodać więcej do tego bałaganu związanego z modułami, należy wspomnieć, że moduły AMD są inne, ponieważ są ładowane asynchronicznie, w przeciwieństwie do "wymaganego" węzła. Aby uzyskać TypeScript do wyprowadzenia, musisz podać parametr "--module AMD" do kompilatora.

W każdym razie, mam nadzieję, że wyjaśniłem sytuację wystarczająco dobrze, aby można było ustalić, czego dokładnie potrzebujesz/chcesz. Typ modułów, z których ostatecznie korzystasz, zależy w istocie od tego, w jaki sposób będziesz ich używać ... tj. Węzeł, sieć lub niektóre połączenie obu.

+0

Dziękuję, to było bardzo pomocne. Ostatecznie zakończyłem pracę bez modułów zewnętrznych: kompilowałem bibliotekę do jednego dużego pliku .js, a aplikację do innego i po prostu ładowałem je za pomocą znaczników script. W plikach źródłowych aplikacji używam komentarzy do pliku biblioteki .d.ts, aby udostępnić jej klasy. – vexator

+0

Czy istnieje sposób na załadowanie dwóch plików do jednego opakowania? Definiuję viewmodels ans export jako klasy w moich plikach maszynopisowych. Następnie, gdy zaimportowane i zawsze kończy się wykonywanie import wrap1 = moduł ("plik1"), importuj wrapper2 = moduł ("plik2"); a następnie nowy wrapper1.Viewmodel1() i nowy wrapper2.ViewModel2(). Byłoby miło, gdyby wszystko mogło być pod jednym modułem, viewmodels.Viewmodel1 i viewmodel.Viewmodel2. Aby to uzyskać, muszę ujawnić wszystkie klasy widoku moedl w tym samym pliku, co ogranicza przegląd. –

+0

@ s093294 Byłem miesiącem od kiedy patrzyłem na maszynopis, więc miej to na uwadze. W każdym razie, używaj '/// ' u góry 'file1.ts' i kompiluj z' tsc - out file.js file1.ts'. Kompilator automatycznie wykryje, że 'plik1.ts' wymaga' file2.ts' (dzięki odwołaniu) i skompiluje go do pojedynczego pliku javascript. Chociaż nie jest to idealne demo dla Ciebie, spójrz na: https://github.com/nxn/ModuleDemo - specjalnie 'make.bat', moduły 'Address' i 'Contacts' (zaimplementowane w wielu plikach), oraz 'default.htm', który ładuje skompilowane pliki javascript. – nxn

Powiązane problemy