2012-10-07 2 views
10

Ho finito il porting di una libreria JavaScript in TypeScript in Visual Studio 2012. Nel complesso le sue circa 60 classi, con ogni classe definita nel proprio file .ts.TypeScript: più progetti in soluzione

Tutte le classi sono definite nello stesso modulo. Uso i commenti di riferimento per ridisegnare in classi definite in altri file. Il layout di ogni file è simile al seguente:

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

module MyModule { 

    export class MyClass { 
     ... 
    } 

} 

Ora ho creato un secondo progetto nella stessa soluzione che sta per essere l'applicazione reale utilizzando la mia libreria di recente porting. Devo includere la mia libreria in qualche modo e immagino che questo sia il sistema del modulo. Tuttavia, non sono sicuro di quale file importare come MyModule è distribuito su dozzine di file. È questo quello che posso usare il file .d.ts?

Inoltre, per poter importare un modulo, è necessario dichiararlo con la parola chiave 'export', ma se lo faccio non viene più trovato dai commenti di riferimento.

Oltre a ciò, entrambi i progetti devono essere compilati in modo che l'output del compilatore possa essere facilmente utilizzato con un caricatore di moduli come requireJS.

Qual è l'approccio migliore per realizzare tutto questo?

Grazie!

risposta

9

Ok, quindi vorrei iniziare dicendo che "Modulo" può significare cose diverse. Ad esempio, c'è il "modello di modulo" che è ciò che crea il tuo "MyModule". Per quanto ne so, TypeScript si riferisce a questi come "Moduli interni" nelle specifiche del linguaggio, e questi differiscono dai "Moduli esterni" che verrebbero caricati con qualcosa come RequireJS. La distinzione principale è che i moduli esterni si aspettano di avere un proprio ambiente isolato con un oggetto "esportazioni" predefinito che possono utilizzare per esportare le loro funzionalità.

Date un'occhiata all'uscita del modulo:

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

Si vede che si sta esportando le cose in "MyModule", che sarà reso disponibile a livello globale per altro script file che si carica con, per esempio, un blocco "script" html. Dato che hai menzionato che ne hai 60, potresti anche impostare il compilatore in modo da generare un singolo file che potresti includere nel markup, invece di caricare ogni file uno per uno.

Passando, dare un'occhiata a ciò che accade per l'uscita se si modifica la dichiarazione del modulo da "modulo MyModule {...}" a "modulo di esportazione MyModule {...}":

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

Come vedete, il vostro modulo sta ancora utilizzando il "modello di modulo" ma è stato assegnato a un membro di "esportazioni", a indicare che è stato progettato per essere caricato con, ad esempio, la funzione "richiede" del nodo.

In questo caso, si vorrebbe utilizzare effettivamente il modulo con questo codice:

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

Annotare il nome di "./MyModule" si riferisce in realtà al nome del file (meno l'estensione .js) il il modulo è definito in (questo è il motivo per cui VS stava dicendo che non poteva trovare quei moduli per te).Il codice dovrebbe compilare a qualcosa di simile:

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

Per aggiungere a questo, non è più nemmeno realmente bisogno di fare qualcosa con la parola chiave "modulo" per avere un modulo. Si potrebbe semplicemente esportare una funzione:

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

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

Questo funziona perché la funzione di 'foo' verrà assegnato direttamente a "esportazioni", che sarà alias di "wrapper" nell'altro file.

Per aggiungere ulteriori dettagli a questo confuso disordine delle cose relative ai moduli, dovrei anche menzionare che i moduli AMD sono diversi ancora perché sono caricati in modo asincrono, a differenza del "bisogno" del nodo. Per fare in modo che TypeScript emetta quelli che devi passare in un parametro "--module AMD" al compilatore.

In ogni caso, spero di aver spiegato la situazione abbastanza bene da essere in grado di capire che cosa esattamente hai bisogno/vuoi. Il tipo di moduli che utilizzerai dipenderà molto da come li userai ... cioè, nodo, web o un mix di entrambi.

+0

Grazie, questo è stato molto utile. Alla fine ho finito di fare a meno di moduli esterni: ho compilato la libreria in un unico grande file .js e l'applicazione in un'altra e semplicemente li ho caricati tramite script-tag. Nei file sorgente dell'applicazione, utilizzo i commenti di riferimento nel file .d.ts della libreria per rendere disponibili le sue classi. – vexator

+0

c'è un modo per caricare due file in un unico wrapper? Definisco i modelli viewmodels come esportazione nei miei file dattiloscritti. Poi, quando importato, finisco sempre per importare wrapper1 = module ("file1"), import wrapper2 = module ("file2"); e quindi nuovo wrapper1.Viewmodel1() e nuovo wrapper2.ViewModel2(). Sarebbe bello se tutto fosse sotto un unico modulo, viewmodels.Viewmodel1 e viewmodel.Viewmodel2. Per ottenere questo ho bisogno di esporre tutte le classi di visualizzazione moedl nello stesso file, che limita la panoramica. –

+0

@ s093294 Da mesi guardavo dattiloscritto, quindi tienilo a mente. Ad ogni modo, usate '/// ' all'inizio di 'file1.ts' e compilate con' tsc --out file.js file1.ts'. Il compilatore capterà automaticamente che 'file1.ts' richiede' file2.ts' (grazie al riferimento) e lo compila in un singolo file javascript. Anche se non è esattamente la demo perfetta per te, dai un'occhiata a: https://github.com/nxn/ModuleDemo - in particolare "make.bat", i moduli "Indirizzo" e "Contatti" (implementati su più file), e 'default.htm', che carica i file javascript compilati. – nxn