直接在浏览器上使用TypeScript脚本语言中国IT实验室收集整理2012-10-22 12:42:23佚名已经有很多社区的文章在介绍 Typescript 这个新的语言,这是理所当然的 - 因为它解决了很多JavaScript的问题,尽管处于起步阶段,却已经显示了巨大的潜力。Typescript 要求你必须预编译来生成JavaScript 代码,现在也可以直接在浏览器上动态编译,但你必须引用 Typescript.js 这个 JS 编译器,这个编译器有 250Kb 大小,这可能是一颗很难咽下的药丸。好在,通过 ASP.NET 的瑞士军刀 —— Web API ,我们可以实现对 Typescript 动态编译为 Javascript。思路为了不用再每次修改 Typescript 后都要手工编译,我们将透过 Web API 来为我们完成这项工作,使用的是定制的 MediaTypeFormatter.你所需要做的就是通过一个特定的预先配置好的 Web API 路由/控制器来引用这个 JS 编译器脚本(Typescript.js),然后让 Web API 管道通过 MediaTypeFormatter 来完成这项重任务。路由和控制器我们在 HTML 中引用编译后的 js 文件如下:为了实现这个目的,新建一个典型的 MVC4, Web API 项目。需要一个定制的路由和一个简单的控制器:config.Routes.MapHttpRoute(name: "DynamicScripts",routeTemplate: "dynamic/{controller}/{name}.{ext}",defaults: new { name = RouteParameter.Optional, ext = RouteParameter.Optional },constraints: new { controller = "Scripts" });public class ScriptsController : ApiController{public string Get(string name){return name;}}这个路由可以让我们传递一个 name 参数和一个扩展(用于匹配所需的 filename.js),然后控制器简单的将文件对应的请求重定向到 formatter 中。插件为了让上述思路可行,我们需要命令行的 Typescript 编译器,可从官方网站 上获取,选择中间那个 (Plugins),推荐 Visual Studio 2012,但 2010 也没关系,我们只关心命令行工具而已。一旦安装成功,你会找到一个名为 TCS.exe 的可执行文件,默认位于 C:\Program Files (x86)\Microsoft SDKs\TypeScript\0.8.0.0\. 将所有编译器文件拷贝到解决方案目录下的 TS 文件夹。格式化器/编译器注意下面的代码应根据你特定的需求进行调整(包括持久化机制、错误处理等等):public class TypeScriptMediaTypeFormatter : MediaTypeFormatter{private static readonly ObjectCache Cache = MemoryCache.Default;public TypeScriptMediaTypeFormatter(){this.AddUriPathExtensionMapping("js", "text/html");}public override void SetDefaultContentHeaders(Type type, System.Net.Http.Headers.HttpContentHeaders headers, System.Net.Http.Headers.MediaTypeHeaderValue mediaType){headers.ContentType = new MediaTypeHeaderValue("application/javascript");}public override bool CanReadType(Type type){return false;}public override bool CanWriteType(Type type){return type == typeof(string);}public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext) {//TODO}}在我们开始写数据到流前,所有代码的执行都是很耗资源的,注意我们设置了一些默认值,我们添加了 UriPathExtensionMapping 这样格式化器就可以处理所有 .js 请求。所有的输出的内容 content-type 将是 application/javascript ,告诉浏览器这些都是 js 文件。也支持请求 text/html, 某些浏览器可能会这样。我们只支持序列化(单向的格式化,非反序列化),而且只接受字符串。WriteToStreamAsyncMediaTypeFormatter 方法根据如下流程将数据写到流中:1.文件名(Typescript 文件)2.检查 TS 文件是否存在3.检查缓存,如果相应的文件已存在则使用MD5 checksum 来确保文件没有改动4.如果没改动则直接从缓存中返回内容5.如果改动了,或者缓存文件不存在则使用 tcs.exe 编译并返回 JS6.将第5步生成的 JS 和 MD5 checksum 内容保存到缓存中以便继续使用public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext){var serverPath = HttpContext.Current.Server.MapPath("~/tsc");var filepath = Path.Combine(serverPath, value.ToString() + ".ts");var jsfilepath = Path.Combine(serverPath, value.ToString() + ".js");var tcs = new TaskCompletionSource