我已经完成了在Visual Studio 2012中将一个JavaScript库移植到TypeScript。总共大约有60个类,每个类都在自己的.ts文件中定义。
所有类都在同一个模块中定义。我使用引用注释来reder到其他文件中定义的类。每个文件的布局如下所示:
///<reference path='./../myotherclass.ts' />
module MyModule {
export class MyClass {
...
}
}
现在我在同一个解决方案中创建了第二个项目,它将成为使用我新移植的库的实际应用程序。我必须以某种方式包括我的库,我想这就是模块系统的用途。但是,我不确定要导入哪些文件,因为MyModule分布在几十个文件中。这是我可以使用.d.ts文件吗?
另外,为了能够导入模块,必须使用'export'关键字进行声明,但如果我这样做,则不再通过引用注释找到它。
最重要的是,应该编译这两个项目,以便编译器输出可以很容易地与像requireJS这样的模块加载器一起使用。
实现这一切的最佳方法是什么?
谢谢!
答案 0 :(得分:9)
好的,让我首先说“模块”可能意味着不同的东西。例如,存在“模块模式”,即“MyModule”创建的模块模式。据我所知,TypeScript在语言规范中将这些称为“内部模块”,这些与“外部模块”不同,您将使用RequireJS加载。主要区别在于外部模块希望拥有自己的隔离环境,并具有预定义的“导出”对象,可用于导出其功能。
看一下模块的输出:
var MyModule;
(function (MyModule) {
var MyClass = (function () {
function MyClass() { }
return MyClass;
})();
MyModule.MyClass = MyClass;
})(MyModule || (MyModule = {}));
您会看到它正在将内容导出到“MyModule”中,这些内容将全局提供给您加载的其他脚本文件,例如,html“script”块。由于你提到你有60个,你可能还可以设置编译器输出一个你可以包含在标记中的文件,而不是逐个加载每个文件。
继续,如果您将模块声明从“模块MyModule {...}”更改为“export module MyModule {...}”,请查看输出会发生什么:
(function (MyModule) {
var MyClass = (function () {
function MyClass() { }
return MyClass;
})();
MyModule.MyClass = MyClass;
})(exports.MyModule || (exports.MyModule = {}));
如您所见,您的模块仍在使用“模块模式”,但它被指定为“exports”的成员,表示它意味着要加载,例如,节点的“require”功能。
在这种情况下,您可能希望使用以下代码实际使用您的模块:
import wrapper = module("./MyModule");
var instance = new wrapper.MyModule.MyClass();
注意“./MyModule”名称实际上是指模块定义的文件名(减去.js扩展名)(这就是为什么VS说它找不到那些模块的原因)您)。代码应编译为类似:
var wrapper = require("./MyModule");
var instance = new wrapper.MyModule.MyClass();
除此之外,您甚至不再需要使用“module”关键字执行任何操作来创建模块。您只需导出一个函数:
// foo.ts
export function foo() {
...
};
// some other file in the same dir
import wrapper = module("./foo");
var result = wrapper.foo();
这是有效的,因为函数'foo'将直接分配给“exports”,它将别名为另一个文件中的“wrapper”。
为了进一步增加这个令人困惑的模块相关内容,我还应该提到AMD模块不同,因为它们是异步加载的,与节点的“require”不同。要让TypeScript输出那些你需要将“--module AMD”参数传递给编译器。
无论如何,我希望我能够很好地解释这种情况,以便你能够弄清楚你究竟需要/想要什么。您最终使用的模块类型将取决于您将如何使用它们...即节点,网络或两者的混合。