参考egret编译顺序说明
我们知道 JavaScript 是一种脚本语言,浏览器按脚本的顺序来执行。实际上浏览器会根据 <script> 标签脚本来载入顺序来执行脚本。当我们的脚本引用了一个未载入的脚本中的变量时,浏览将报出相应的错误。
一般情况下我们在 Egret 项目中并不需要手动处理编译顺序,因为我们的编译器已经帮助我们处理好了。但是有一种情况是编译器不能处理的,需要我们手动加上 <reference> 标签来告诉编译器我们的类的依赖关系。
首先我们建立几个测试类,项目的结构如下:
如上所示,创建了一个 Test 文件夹,内部创建了 Call 文件夹,在 Call 内部创建了 TestCall.ts。同时在 Test 文件夹内创建 TestA.ts 和 TestB.ts。其余的 Main.ts 和 LoadingUI.ts 这里用不到,我们并不用去关注它们。
在 TestA.ts 中代码如下:
class TestA{
public static arr:Array<any> = ["t","e","s","t","c","a","l","l"];
}
TestB.ts 中代码如下:
class TestB{
public static testBStr:string = TestA.arr.join("");
}
这两个类内容很简单,都只有一个静态成员。其中 TestA 类存放了一个数组,TestB 类将这个数组的内容拼接成一个字符串并保存下来。到目前为止我们编译运行并没有发现异常。
下面在TestCall.ts 中加入对 TestB 类的调用。
class TestCall{
public static test:any = egret.getDefinitionByName(TestB.testBStr);
}
编译运行之后发现浏览器会报如下TestB.js:11 Uncaught ReferenceError错误:
那么当我们添加了 TestB.testBstr的调用之后浏览器发现 TestA 类并没有被定义,进而导致 testBStr 这个属性页找不到了。当我们编译之后发生了什么呢,检查一下生成的 index.html 文件会发现 TestB.js 是在 TestCall.js 之前加载的,而 TestA.js 是在最后加载的。当 TestB.js 调用 TestA.js 中的文件的内容时浏览器将会报错。
上面的调用关系在代码中显然是成立的,编译器并没有报错。而编译器并没有生成正确的载入顺序,主要是因为其无法确认这种类的静态成员的互相引用的顺序。当在 TestCall.ts 中引用了TestB.ts 中的内容时自动将 TestB.js 放在 TestCall.js 之前进行加载。由于无法检测到 TestB.ts 中对 TestA.ts 的静态成员的引用,所以导致了以上情况的发生。
解决方法
这种情况解决方法也很简单,就是告诉编译器我们的类的依赖关系。在 TypeScript 中,使用<reference>标签来表示引用关系。在 reference 标签中可以标记依赖文件的相对路径。所以只需要在 TestB 类之前加入如下注释即可:
///<reference path="TestA.ts" />
class TestB{
public static testBStr:string = TestA.arr.join("");
}
上面这种情况一般发生在静态成员的引用上,还有其他情况在极小概率下可能导致该现象,如果遇到可以加入依赖关系标签来告诉编译器正确的加载方式。
参考
js文件三斜杠注释///reference path用途
编辑某个js文件时,要想这个js文件出现其他js成员的ide提示,可以再js文件开头使用3个斜杠注释和reference指令的path指向此js文件路径,这样在编写这个js文件时,ide就会自动出现path指向的js文件中的成员。
如导入jquery框架,在vs2013中编写js文件时,jquery的标志性字符$就会自动出现在ide中,并且其方法也会一起ide提示,大大加快代码编写速度。
注意:reference注释需要放在js文件开头(并不需要一定是第一行,前面可以有空白行),但是前面只能是空白行,不能有其他js代码。注释需要为3个斜杠///,经测试多一个少一个都不行,应该延续了C#的注释。可以使用注释///reference导入多个会引用到的js文件。
///<reference path="jquery1.4.2.js">
///<reference path="hightlight.js">
提醒:js文件三斜杠注释///reference path导入的文件是给ide用的,你的html页面注意一定也要导入对应的js文件,要不会报错。
参考
使用Typescript来写javascript
TypeScript 三斜线指令
/// <reference path="../../libs/underscore.browser.d.ts"/>
它是一种注释,告诉typescript编译器,当前文件使用了哪些声明文件,以帮助编辑器提示信息,及编译器检查类型。这种注释很重要,如果后面的路径不对,则编译会失败。
引用的文件以 .d.ts 结尾,它们是一种声明文件,就像是c语言中的header文件,只包含了类或函数的签名,而没有实际内容,用于编辑器提示和编译器验证。它们的内容形如:
declare interface UnderscoreVoidListIterator {
(element : any, index : number, list : any[]) : void;
}
declare interface UnderscoreMemoListIterator {
(memo : any, element : any, index : number, list : any[]) : any;
}
declare interface UnderscoreListIterator {
(element : any, index : number, list : any[]) : any;
}
这种文件很重要,因为我们要想使用第三方的js库,一般都需要手动做出这样的声明文件,才能在typesafe的环境中使用它们。只需要以注释的方式写上即可,不需要在实际代码中声明或引用什么。