将过时的JavaScript库与更新的TypeScript集成
Integrating dated JavaScript libraries with updated TypeScript
我和我的团队正在构建一个大型web应用程序项目,该项目使用流行JavaScript库(jQuery、Backbone、Undercore等)的旧版本。我们目前正在尝试逐步将TypeScript用于新的解决方案以及替换现有的JavaScript代码。因为我们的项目在很大程度上依赖于特定的JS库版本(例如jQuery 1.8.3),所以将这些库更新到最新版本比下载并放入最新版本稍微复杂一些。
这给我们带来了一个分阶段使用TypeScript的问题;我们需要与最新TypeScript标准兼容的过时JS库版本的声明。尽管在为最新版本的JS库,特定于最近版的TypeScript,它不提供与最新TypeScript标准兼容的旧JS库版本的声明文件。
似乎随着TypeScript的发展,所有旧的库声明(例如jQuery-1.8.3.d.ts)都被抛在了脑后,因为这些库正在同时发展。这是完全可以理解的,因为我不希望社区中有太多的努力来不断更新过时的库声明文件,以便它们与新的TypeScript标准兼容。
所以我的问题是:对于严重依赖旧JS库的新TypeScript代码,分阶段使用的最佳方法是什么
下面是我遇到的一个问题的例子。我本质上是在尝试使用TypeScript创建一个Backbone应用程序。
// Model.ts
import Backbone = require("backbone");
export class NewModel extends Backbone.Model {
...
}
因为我们使用的是带有require.js的AMD,所以我们得到了如下内容:
// 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'
}
}
});
但是,TypeScript不允许我们编译此代码,除非我们有一个主干.d.ts,它描述了我们的骨干.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 {
...
}
如果我们没有这些声明,那么我们就没有主干模块的环境声明,因此不能在TypeScript中使用extend Backbone.Model
,因为Backbone.Model
在任何地方都没有定义为类。这是一个有点夸张的示例问题,因为无论版本如何,Model
类类型都存在于所有"主干.d.ts"文件中。然而,如果没有一个准确的.d.ts文件来表示代码,JS库还有一些更微妙的变化,可能会导致代码中断。
话虽如此,只要你只使用相关JS库中实际存在的部分,并且直接使用它们,你也可以使用更新版本的.d.ts文件(我们一直在做)。否则,如果您使用了一个不存在的函数,或者如果您传递了太多参数,那么只有在实际调用该函数时才会看到该错误。TypeScript不会接受它,因为它的信息完全基于.d.ts文件的信息。
我们可以使用amd依赖性工作来生成define
需求,比如:
// Model.ts
/// <amd-dependency path="backbone" />
var Backbone = require("backbone");
export class NewModel extends Backbone.Model {
...
}
这将生成以下内容:
// Model.js
...
define(['require', 'exports', 'backbone'], function(require, exports) {
var Backbone = require('backbone');
...
}
这给了我们想要的Backbone
引用,但TypeScript仍然会抱怨,因为它不知道我们正在声明的Backbone
变量。换句话说,它没有提供.d.ts文件提供的结构。
尽管我们在.js文件和相关的.d.ts文件之间缺乏相关性,但我们的大多数TypeScript解决方案实际上都能正常工作。我担心的是:将来这种差异会在我们的应用程序中引起重大问题吗
现在,我能想到的最好的解决方案是:
- 获取最接近我们JS库版本的.d.ts版本,并对其进行更新,使其与最新的TypeScript标准兼容
- 使用最新的.d.ts文件,并在遇到问题时相应地进行更新
我对这两种解决方案都不是特别兴奋,这就是为什么我要寻求另一种意见。如果有人在这一点上仍然和我在一起(很抱歉拖延),那么我将感谢你提出的解决方案。
这可能是一个粗略的问题,我们的团队在TypeScript的早期肯定会处理这个问题。最终,我们从绝对类型上的d.ts文件版本开始,并根据我们的需要对其进行调整。对于许多库,我们发现键入没有使用新的语言功能,不完整,或者在某些情况下完全错误。我们已经尽了最大努力,在有意义的地方做出贡献。
考虑到你正在考虑的两种方法,我会选择#1。当语言以极快的速度发展时,让d.ts文件跟上最新的TypeScript标准更是一个问题。虽然我仍然预计v2会有很多新功能,但v1相当稳定。在1.0之前的运行过程中,语言似乎每月都会发生变化。我认为我们现在不需要处理这种程度的流失:)
- Javascript循环不会自我更新
- 添加文字和评论功能更新Div
- AngularJS:ng之后,重复$scope值未按预期更新
- 如何通过数组更新角度子范围
- Ajax聊天消息重复而不仅仅是更新
- Foreach无法在Typescript中工作
- 通过CSV文件上载更新数据库表
- 平均值:无法将数据更新到数据库
- 扩展SVGTextElement时出现Typescript Uncaught TypeError
- $rootScope未使用forEach进行更新
- d3基于用户选择动态更新节点
- 为什么无法在TypeScript中导出类实例
- 从Typescript 1.6.2中的内置Array扩展的类在使用[]运算符时不会更新长度
- 将过时的JavaScript库与更新的TypeScript集成
- 作用域变量不会用typescript在控制器angularjs上更新
- 如何在构造函数typescript中5秒后更新作用域值
- Typescript:从输入更新值
- Visual Studio 2015 RTM -在更新TypeScript工具后失去对JavaScript的支持
- 在Atom编辑器中找到Typescript版本,并在必要时更新Typescript
- Atom-typescript会更新.ts文件,但HTML中的更改不会在保存时更新