2012-10-08 46 views
8

我不知道是否有可能有一個「導出模塊」跨多個文件傳播。如何在多個AMD文件中傳播模塊?

如果我有文件Contact.ts:

// file Contact.ts 
export module Contacts { 
    export class Contact { 
     ... 
    } 
} 

和另一ContactView.ts

// file ContactView.ts 
export module Contacts { 
    export class ContactView { 
     model: Contact; // <--- is not recognized 
    } 
} 

然後TSC是不承認的聯繫類。正如你所看到的,Contact和ContactView被聲明爲駐留在同一個模塊中,並且根據規範它應該工作。

我正在構建一個使用require.js和AMD模式的複合應用程序,所以我必須使用「導出模塊」聲明。

我應該做某種類型的「提前聲明」還是一些棘手的「導入」?

感謝您的意見。

編輯:目前我通過導入分別加載每個模塊,但是,如果您會注意到,它會造成代碼和大量「導入」依賴項的巨大浪費。 我的問題是如果有一種方法使用相同的名稱空間(即聯繫人)讓我知道我不打算導入的TS。 我正在尋找正常的//命令,但它不起作用。我甚至嘗試過* .d.ts聲明文件,目前爲止沒有成功。

回答

6

該規範允許您跨多個文件定義內部模塊(本質上,內部模塊指JavaScript模塊模式)。 外部模塊(例如AMD或CommonJS模塊)的工作原理是每個文件都是實際的「代碼模塊」,並且其中的命名空間/命名無關緊要,因爲模塊無論如何都會被加載到它自己的新對象中。

你可以寫下面的代碼加載ContactView.ts模塊內的Contact.ts模塊:

// file ContactView.ts  
import mod = module("./Contact"); 

export module Contacts { 
    export class ContactView { 
     model: mod.Contacts.Contact; // <--- will be recognized 
    } 
} 

,並應工作不夠好,但如果你想訪問的內容在另一個領域兩個模塊(用於例如讓自己一個新的接觸模型),你將不得不進口基本上他們兩個:

import c = module("./Contact"); 
import cv = module("./ContactView"); 

我認爲這是不夠精細,因爲你清楚地說明你的依賴。缺點是他們不會共享一個共同的父對象,所以讓他們都在一個「聯繫」模塊模式可能不是很好用。

另一種選擇是導出「Contact」以及「ContactView」,如下所示(授予此代碼有點愚蠢,因爲您已經在通過ContactView的模型屬性完成該操作,但絕不會少於... ):

export module Contacts { 
    export class ContactView { 
     model: mod.Contacts.Contact; 
     constructor() { 
      this.model = new mod.Contacts.Contact(); 
     } 
    } 

    export var Contact = mod.Contacts.Contact; 
} 

所以你可以在加載ContactView後訪問它。編輯:順便說一句,你不僅限於通過「導出模塊名稱{...}」導出模塊,你可以導出任何東西,因爲文件本身就是模塊。所以你可以有一個只有「導出函數foo(){...}」的文件,沒有任何模塊模式代碼包裝它。編輯2:它看起來像AMD可能具有加載多個依賴關係和構建「模塊」的功能,但我不知道如何在TS中工作,這裏有一個鏈接:http://www.adobe.com/devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html(構造函數模塊) 。

+0

這正是我現在所做的 - 通過導入單獨加載每個模塊,但是,如果您注意到,會造成代碼和數百個依賴關係的巨大浪費。 我的問題是如果有一種方法使用相同的名稱空間(即聯繫人)讓我知道我不打算導入的TS。 我正在研究正常的// 命令,但它不起作用。 – IgorM

+1

在這種情況下,不要導出模塊Contacts,只需在所有文件中將其定義爲'module Contacts {...}',使用/// (這適用於內部模塊)來幫助TS找到它們,併爲AMD模塊創建一個新文件,該文件只有'export var contacts = Contacts';在它中,所以你可以通過AMD加載整個東西。你必須確保你輸出的var與模塊的名字不一樣,否則發出的代碼將不起作用。我不能遺憾地爲此編寫代碼演示,但如果需要的話,我可以稍後再做。 – nxn

+0

再想一想,您可能需要創建一個makefile,將每個模塊輸出到它自己的js文件中。 – nxn

4

我在同一個問題上掙扎了一段時間,只是想分享我在做什麼,以防其他人在這個問題上徘徊。

首先,我定義自己,宣稱所有的模塊中的文件的參考文件:

/// <reference path="_contacts.dependencies.ts" /> 
/// <reference path="../contacts/Contact.ts" /> 
/// <reference path="../contacts/ContactView.ts" /> 
/// <reference path="../contacts/ContactModel.ts" /> 

注意的是,文件中指定的路徑是相對於引用文件本身(_contacts.ts)的位置,不像.js參考文件。我的目錄結構如下所示:

modules 
    references // all of the reference files 
     knockout 
     underscore 
     // ... a subfolder for every 3rd party library used 
    contacts 
    commerce 
    // ... other modules at same level as contacts 

返回參考文件本身。第一行包含一個單獨的參考文件,其中列出了模塊使用的所有外部庫,例如下劃線,矩形或任何其他現有庫,您有一個定義文件的.d.ts定義文件。其餘的行是組成該模塊的文件。

所有文件,該模塊的一部分裏面,我引用了上述文件:

/// <reference path="../references/_contacts.ts" /> 
module Contacts { 
    export class Contact { 
     public model: ContactModel; 
     // ... 
    } 
} 

同樣,你可以創建一個單一的參考文件,列出所有你的模塊:

/// <reference path="_address.ts" /> 
/// <reference path="_contacts.ts" /> 
/// <reference path="_commerce.ts" /> 

而且只需從源文件中指出這一點即可。

雖然這並不能解決發出的代碼在單獨文件中的問題。對於這個問題,我使用JavaScript縮小工具,它可以將多個文件捆綁成一個源文件。根據您的編譯設置和用例需求,您可能需要在生成的代碼上應用一些包裝,使其作爲AMD模塊(不太熟悉該部分)。

+0

我真的很喜歡這個解決方案,謝謝! – parliament

+0

至於最後一部分,你也可以使用它在BeforeBuild中使用這個編譯成單個文件:'"%(fullpath)"','')「/>編譯_references.ts文件本身可以確保您如何佈置引用的正確順序。我不認爲--module標誌只會讓它作爲AMD模塊工作。我認爲你需要生成一個像這樣的定義文件:tsc --declarations file1.ts file2.ts file3.ts ... – parliament

+0

其實,在這裏解決了一個與這種方法相關的錯誤:http://typescript.codeplex .com/workitem/836 – parliament

相關問題