TypeScript中的内部和外部模块有什么区别?
我花了一些时间阅读Typescript语言规范,对内部和外部模块之间的区别有些困惑。 以下是从规范中直接得到的描述:
内部模块(第9.2.2节)是本地或其他模块的导出成员(包括全局模块和外部模块)。 内部模块使用ModuleDeclarations声明它们的名称和正文。 具有多个标识符的名称path相当于一系列嵌套的内部模块声明。
外部模块(第9.4节)是使用外部模块名称引用的代码的单独加载主体。 外部模块被编写为一个单独的源文件,其中至less包含一个导入或导出声明。 另外,可以在全局模块中使用AmbientModuleDeclarations声明外部模块,这些模块直接将外部模块名称指定为string文字。 这在第0节进一步描述。
从我所理解的,我认为外部模块对应于typescript文件,而不包含简单地导出一组types和/或variables的模块定义。 从另一个打字稿文件,我可以简单地导入foo.ts中的外部模块与import foo = module("foo");
有人可以向我解释外部和内部模块之间的命运吗?
规范的9.3和9.4节更加清楚地解释了这一点。 我将在这里重现这些部分给出的一些例子。
外部模块
假设下面的代码在main.ts
。
import log = module("log"); log.message("hello");
这个文件引用一个外部模块log
,由任何log.ts
定义。
export function message(s: string) { console.log(s); }
请注意, log.ts
不会在任何地方使用module
关键字。 它只是出口的东西export
。
内部模块
这个文件有两个内部模块, XYZ
。
module ABC { import XYZ = XYZ; export function ping(x: number) { if (x > 0) XYZ.pong(x – 1); } } module XYZ { import ABC = ABC; export function pong(x: number) { if (x > 0) ABC.ping(x – 1); } }
这些行为(主要)像外部模块,但它们包含在一个文件中,您不必引用任何外部文件来使用它们。 定义时,它们必须包含在module
块内。
根据安德斯介绍: http ://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript(34:40)和Typescript文档,外部模块是基于顶级AMD(asynchronous模型定义)或CommonJS的。
外部模块在某种意义上是有用的,它们隐藏了模块定义的内部语句,只显示与声明variables相关的方法和参数。
假设你有一个定义了log
方法的Main
类放置在一个transfer.js
文件中。 Main
类的内部方法仅在导入源js文件顶部的transfer.js
文件时才可见: ///<reference path="transfer.js"/>
。 这样编译器就可以在运行时消除所有js文件的遍历。
这是使用外部模块的巨大好处。 另一个是当你试图引用一个外部的方法或类在正常的自顶向下的JavaScriptstream定义晚于方法调用。 使用外部模块,被引用的类仅在方法调用时被实例化。
内部模块:
- 你可以在你的typescritp文件中定义模块。
- 在模块中定义的所有variables都被限定在模块中并从全局范围中删除。
- 当你编译你的打字稿文件时,你的模块被转换成variables,这些variables可以根据需要进行嵌套,以形成名称空间对象。 请注意,使用IIFE(立即调用的函数expression式)将在模块内定义的类整齐地隔离开来。
- 下面的代码显示MyClassvariables的作用域为MyInternalModule模块。 他们不能被访问的模块之外,这就是为什么代码的最后一行显示错误找不到名称MyClass。
- 您可以使用export关键字访问模块外部的variables。
- 您也可以扩展内部模块,跨文件共享,并使用三斜杠语法引用它们(///)
例如 :
module MyInternalModule{ class MyClass{ //if We write export keyword before the MyClass then last line works fine constructor ( public height: number, public width: number) { } } //working properly var obj1 = new MyClass(10, 4); } // it wont work //Because the out of the scope var obj2 = new MyInternalModule.MyClass(10,4) //shows error: can not find name MyClass
编译版本的脚本:
var MyInternalModule; (function (MyInternalModule) { var MyClass = (function () { function MyClass(height, width) { this.height = height; this.width = width; } return MyClass; })(); //working properly var obj1 = new MyClass(10, 4); })(MyInternalModule || (MyInternalModule = {}));
外部模块:
例如 :
// bootstrapper.ts file // imports the greeter.ts file as the greeter module import gt = module('greeter'); export function run() { var el = document.getElementById('content'); var greeter = new gt.Greeter(el); greeter.start(); } // greeter.ts file // exports the entire module export class Greeter { start() { this.timerToken = setInterval(() => this.span.innerText = new Date().toUTCString(), 500); } }