2014-09-05 62 views
1

我和我的团队正在构建一个使用较早版本流行JavaScript库(jQuery,Backbone,Underscore等)的大型Web应用程序项目。我们目前正在尝试使用TypeScript来解决新的解决方案以及替换现有的JavaScript代码。因为我们的项目严重依赖特定的JS库版本(例如jQuery 1.8.3),所以将这些库更新为最新版本稍微复杂一些,不仅仅是下载和下载最新版本。将更新日期的JavaScript库与更新后的TypeScript集成

这对我们来说在逐步改变TypeScript方面会产生一个问题;我们需要声明与最新的TypeScript标准兼容的过时的JS库版本。虽然DefinitelyTyped在提供申报文件的 最新版本 JS库的特定于最新版本打字稿的做了伟大的工作,它不为年长 JS库版本能与最新的兼容提供报关文件TypeScript标准。

看起来,随着TypeScript的发展,所有较旧的库声明(例如jQuery-1.8.3.d.ts)都被留下了,因为这些库同时在不断发展。这是完全可以理解的,因为我不希望社区中有很多努力不断更新日期库的声明文件,以便它们与新的TypeScript标准兼容。

所以我的问题是:什么是最好的方式来逐步在新的TypeScript代码,严重依赖老的JS库?

下面是我遇到的一个问题的例子。我基本上试图用TypeScript创建一个Backbone应用程序。

// Model.ts 
import Backbone = require("backbone"); 
export class NewModel extends Backbone.Model { 
    ... 
} 

而且因为我们使用了AMD require.js我们得到类似以下内容:

// Model.js 
... 
define(['require', 'exports', 'backbone'], function(require, exports, Backbone) { 
... 
} 

这是伟大的,它正是我们希望,因为我们require.config文件的输出定义了所有我们需要的库:

// Config.ts 
require.config({ 
    baseUrl: './', 
    paths: { 
     'jquery': '../jquery-1.8.3.min', 
     'underscore': '../underscore/underscore.min', 
     'backbone': '../backbone/backbone', 
     'text': '../require/text' 
    }, 
    shim: { 
     jquery: { 
      exports: '$' 
     }, 
      underscore: { 
      exports: '_' 
     }, 
     backbone: { 
      deps: ['underscore', 'jquery'], 
      exports: 'Backbone' 
     } 
    } 
}); 

然而,打字稿不会让除非我们有一个backbone.d我们编译这段代码.ts,它描述了我们的backbone.js库的结构,并提供了“主干”模块的环境声明。

// backbone.d.ts 
declare module Backbone { 
    ... 
    export class Model extends ModelBase { 
     ... 
    } 
    ... 
} 
declare module 'backbone' { 
    export = Backbone; 
} 

// Model.ts 
/// <reference path="path/to/backbone.d.ts" /> 
import Backbone = require("backbone") 
export class NewModel extends Backbone.Model { 
    ... 
} 

如果我们没有这些声明,然后我们有骨干模块的周围没有申报,因此可以在不打字稿因为extend Backbone.ModelBackbone.Model任何地方没有定义为一类。这是一个夸大的示例问题,因为Model类类型存在于所有'backbone.d.ts'文件中,而不考虑版本。然而,如果你没有一个精确的.d.ts文件来代表它,那么JS库会有更微妙的变化,导致代码崩溃。这就是说,你也可以使用更新版本的.d.ts文件(我们一直在做),只要你只使用实际存在相关JS库的部分,并且作为只要你直接使用它们。否则,如果你使用一个不存在的函数,或者如果你传递了一个函数太多的参数,那么当这个函数实际被调用时你只会看到这个错误。 TypeScript不会选择它,因为它的信息完全基于.d.ts文件。

// Model.ts 
/// <amd-dependency path="backbone" /> 
var Backbone = require("backbone"); 
export class NewModel extends Backbone.Model { 
    ... 
} 

这将产生以下:

我们可以使用AMD依赖工作周围的东西,如产生define要求

// Model.js 
... 
define(['require', 'exports', 'backbone'], function(require, exports) { 
var Backbone = require('backbone'); 
... 
} 

这给了我们Backbone引用,我们希望但是TypeScript仍然抱怨,因为它不知道我们声明的Backbone变量。换句话说,它不提供.d.ts文件提供的结构。

尽管我们缺乏.js文件与其关联的.d.ts文件之间的关联,但我们的大多数TypeScript解决方案实际上都在按照他们应该的方式工作。我的关注点是:未来的这种差异会在我们的应用程序中造成重大问题吗?

现在,我能想到的最好的解决方案是:

  1. 获取.d.ts版本最接近我们JS库的版本和更新他们,使他们与最新的打字稿标准兼容。
  2. 使用最新的.d.ts文件,并在遇到问题时相应地更新它们。

我对任何一种解决方案都不是特别激动,这就是为什么我要伸出援手寻求另一种意见。如果有人仍然在这里(抱歉拖延这一点),那么我会很感激你提出的解决方案。

回答

1

这可能是一个粗糙的问题,也是我们团队在TypeScript早期处理的一些问题。我们最终从绝对键入的d.ts文件版本开始,并根据我们的需要进行调整。对于很多图书馆,我们发现打字不使用新的语言功能,不完整,或者在某些情况下是错误的。我们已尽了最大努力回馈它有意义的地方。

鉴于你正在考虑的两种方法,我会去#1。当语言快速发展时,使d.ts文件保持最新以及最新的TypeScript标准更成为一个问题。虽然我仍然期望v2中有很多新功能,但v1相当稳定。在运行到1.0的过程中,语言似乎每个月都有变化。我不认为我们现在需要处理这种级别的流失:)