2013-05-11 36 views
3

我有一段不可能的时间试图在Chrome开发工具中使用TypeScript调试工作。我为我的所有.ts文件生成了源映射,并且javascript看起来正确,但Chrome只加载了index.html中引用的js文件,并忽略了所有模块。这有点合理,因为Typescript编译器似乎没有对我的模块做任何事情。如果有人能够在下面的例子中解释我做错了什么,那会很好。如何使用源映射来调试模块化的TypeScript?

我的项目设置是这样的:

root/ 
    src/ 
    Company.ts 
    User.ts 
    app.ts 
    index.html 

Company.ts

module Company { 

    export class Job { 
     public title:string; 
     public description:string; 

     constructor(title:string, desc:string){ 
      this.title = title; 
      this.description = desc; 
     }; 
    } 
} 

User.ts

///<reference path="Company.ts"/> 

module User { 
    export class Person { 
     public first:string; 
     public last:string; 
     private myJob:Company.Job; 
     private myAccount:User.Account; 

     constructor(firstName:string, lastName:string){ 
      this.first = firstName; 
      this.last = lastName; 
     } 

     public getName():string{ 
      return this.first + ' ' + this.last; 
     } 

     public setJob(job:Company.Job){ 
      this.myJob = job; 
     } 

     public setAccount(acct:User.Account){ 
      this.myAccount = acct; 
     } 

     public toString():string{ 
      return "User: " + this.getName() 
        + "\nUsername: " + this.myAccount.userName 
        + "\nJob: " + this.myJob.title; 
     } 
    } 

    export class Account { 
     public userName:string; 
     private _password:string; 

     constructor(user:Person){ 
      this.userName = user.first[0] + user.last; 
      this._password = '12345'; 
     } 
    } 
} 

app.ts

///<reference path="src/User.ts"/> 
///<reference path="src/Company.ts"/> 

(function go(){ 
    var user1:User.Person = new User.Person('Bill','Braxton'); 
    var acct1:User.Account = new User.Account(user1); 
    var job1:Company.Job = new Company.Job('Greeter','Greet'); 

    user1.setAccount(acct1); 
    user1.setJob(job1); 
    console.log(user1.toString()); 
}()); 

的index.html

<!DOCTYPE html> 
<html> 
<head> 
    <title>TypeScript Test</title> 
    <script src="app.js"/> 
    <script> 
     go(); 
    </script> 
</head> 
<body> 

</body> 
</html> 

编译命令

TSC --sourcemap --target ES5 --module CommonJS的file.ts

当我在Chrome中打开index.html并打开“来源”面板的Chrome开发工具时,它会向我显示app.js和app.ts,但不会显示其他.ts模块。所以app.ts的源代码图工作正常,但我如何加载其他模块,以便它们可以在Chrome中进行调试?

回答

6

当您使用引用注释时,您必须自己加载所有模块(即添加多个脚本标记或合并和缩小文件等)。

如果要使用模块加载器,则需要使用import语句,该语句将被转换为您选择的模块加载器(可能为Web的RequireJS)的require方法调用。

实施例1 - DIY

<script src="/src/Company.js"></script> 
<script src="/src/User.js"></script> 
<script src="app.js"></script> 

实施例2 - RequireJS

SRC/Company.ts

export class Job { 
    public title: string; 
    public description: string; 

    constructor(title: string, desc: string) { 
     this.title = title; 
     this.description = desc; 
    } 
} 

注意,我已经删除了module声明。文件名变为当您使用RequireJS导入模块的模块名称...

的src/User.ts

import company = module('Company'); 

export class Account { 
    public userName: string; 
    private _password: string; 

    constructor(user: Person) { 
     this.userName = user.first[0] + user.last; 
     this._password = '12345'; 
    } 
} 

export class Person { 
    public first: string; 
    public last: string; 
    private myJob: company.Job; 
    private myAccount: Account; 

    constructor(firstName: string, lastName: string) { 
     this.first = firstName; 
     this.last = lastName; 
    } 

    public getName(): string { 
     return this.first + ' ' + this.last; 
    } 

    public setJob(job: company.Job) { 
     this.myJob = job; 
    } 

    public setAccount(acct: Account) { 
     this.myAccount = acct; 
    } 

    public toString(): string { 
     return "User: " + this.getName() 
      + "\nUsername: " //+ this.myAccount.userName 
      + "\nJob: " + this.myJob.title; 
    } 
} 

这里一对夫妇的变化 - 我们有import语句,而不是一个评论指向该文件。我们在这里也参考Account而不是User.Account。封装模块再次作为文件是模块。

app.ts

import Company = module('src/Company'); 
import User = module('src/User'); 

(function go() { 
    var user1: User.Person = new User.Person('Bill', 'Braxton'); 
    var acct1: User.Account = new User.Account(user1); 
    var job1: Company.Job = new Company.Job('Greeter', 'Greet'); 

    user1.setAccount(acct1); 
    user1.setJob(job1); 
    console.log(user1.toString()); 
}()); 

导入语句再次在这里。作为一个方面说明,go函数看起来是立即执行的,所以你不需要再次手动调用它 - 你可以删除函数名来阻止这个意外完成。

的Index.html

<script data-main="app.js" src="require.js"></script> 

您需要include the RequireJS script在您的项目。你只需要将它指向你的第一个文件,它会加载所有的文件。您将在编译的JavaScript,你import语句被转换成调用的RequireJS require功能注意:

var Company = require("./src/Company"); 
var User = require("./src/User"); 

这会触发RequireJS加载脚本为您服务。

您也可以use RequireJS manually if you want more control(即使用require方法,而不是直接使用import语句。

+0

好吧,我在想,一个模块加载可能需要手动实现。您打算在您的最后一个环节句子?它看起来像是用蓝色突出显示,但没有链接 – eterps 2013-05-11 19:48:23

+0

我添加了RequireJS示例 – Fenton 2013-05-11 19:57:41

+1

好东西!我避免使用RequireJS,因为我的印象是TypeScript更适合CommonJS规范(和默认情况下使用),但这很好,因为我更喜欢AMD/RequireJS,感谢您的详细解答! – eterps 2013-05-11 20:47:17