Typescript 如何跨多个AMD文件传播模块?

Typescript 如何跨多个AMD文件传播模块?,typescript,Typescript,我不知道是否有可能让一个“导出模块”跨越多个文件 如果我有Contact.ts文件: // file Contact.ts export module Contacts { export class Contact { ... } } 还有另一个ContactView.ts // file ContactView.ts export module Contacts { export class ContactView { model: Contact;

我不知道是否有可能让一个“导出模块”跨越多个文件

如果我有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
   }
}
//文件ContactView.ts
导出模块联系人{
导出类ContactView{

model:Contact;//该规范允许您跨多个文件定义内部模块(本质上,内部模块指的是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
   }
}
我认为这很好,因为你清楚地说明了你的依赖关系。缺点是它们不会共享一个共同的父对象,所以让它们都处于“联系”模块模式可能没有多大用处

另一个选项是将“Contact”与“ContactView”一起导出,如下所示(假定此代码有点傻,因为您已经通过ContactView的model属性完成了这项工作,但决不能少…):

因此,您可以在加载ContactView后访问它

编辑:顺便说一下,您不仅限于通过“导出模块名{…}”导出模块,还可以导出任何内容,因为文件本身就是模块。因此,您可以拥有一个只有“导出函数foo(){…}”的文件,而不需要任何模块模式代码包装它


EDIT2:看起来AMD可能具有加载多个依赖项并从这些依赖项构建“模块”的功能,但我不知道这在TS中会如何工作,这里有一个链接,它是:(构造函数模块).

我为同一个问题挣扎了一段时间,只想分享一下我在做什么,以防其他人发现这个问题

首先,我为自己定义了一个引用文件,用于声明模块中的所有文件:

/// <reference path="_contacts.dependencies.ts" />
/// <reference path="../contacts/Contact.ts" />
/// <reference path="../contacts/ContactView.ts" />
/// <reference path="../contacts/ContactModel.ts" />
回到参考文件本身。第一行包括一个单独的参考文件,列出模块使用的所有外部库,如下划线、矩或任何其他现有库,您有一个
.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模块工作(还不太熟悉该部分)。

这正是我现在所做的-通过导入分别加载每个模块,但是,如果您注意到的话,这会造成大量代码浪费和数百个依赖项。我的问题是,是否有办法使用相同的命名空间(即联系人)为了让您知道我不想导入的TS。我查看了正常的//命令,但它不起作用。在这种情况下,不要导出模块联系人,只需在所有文件中将其定义为“模块联系人{…}”,使用//(这适用于内部模块)为了帮助TS找到它们,并为AMD模块创建一个新文件,其中只有“export var contacts=contacts;”,这样您就可以通过AMD加载整个内容。您必须确保您导出的变量与模块的确切名称不同,否则发出的代码将无法工作。不幸的是,我无法为此编写代码演示目前,如果需要,我可以稍后再做。再考虑一下,您可能需要创建一个makefile,将每个模块输出到自己的js文件中。您的演示对于获得正确的设置非常有帮助。非常感谢!至于最后一部分,您也可以使用它在BeforeBuild中编译为单个文件:编译_references.ts文件本身确保了设置引用的正确顺序。我不认为--module flag会让它像AMD模块一样工作。为此,我认为您需要生成这样的定义文件:tsc--declarations file1.ts file2.ts file3.ts…实际上,刚刚解决了一个与此方法相关的错误:@Vazgen Th不过,我已经切换到JetBrains WebStorm IDE进行TypeScript开发,它现在具有本机TS支持。它会根据需要自动编译文件,并且通常工作得很好(而且不会像VS那样污染源文件夹).至于捆绑,当所有东西都捆绑在一起时,我找不到绕过源代码的方法,所以我放弃了,现在链接到各个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
/// <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" />