我和我的團隊正在構建一個使用較早版本流行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.Model
是Backbone.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解決方案實際上都在按照他們應該的方式工作。我的關注點是:未來的這種差異會在我們的應用程序中造成重大問題嗎?
現在,我能想到的最好的解決方案是:
- 獲取.d.ts版本最接近我們JS庫的版本和更新他們,使他們與最新的打字稿標準兼容。
- 使用最新的.d.ts文件,並在遇到問題時相應地更新它們。
我對任何一種解決方案都不是特別激動,這就是爲什麼我要伸出援手尋求另一種意見。如果有人仍然在這裏(抱歉拖延這一點),那麼我會很感激你提出的解決方案。