2014-09-05 59 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的過程中,語言似乎每個月都有變化。我不認爲我們現在需要處理這種級別的流失:)