动机
异步模块定义 (AMD) 和 RequireJS 是我过去四年中 Javascript 代码模块化的选择。但是我正在开发的企业 Web 应用程序正在增长,管理代码库越来越难。我做了一些技术研究,并决定将项目迁移到 TypeScript。
TypeScript 勾选了我愿望清单中的所有要点:
- 支持AMD格式,代码可以增量迁移
- JavaScript 是合法的 TypeScript
- 对更严格的接口进行类型检查
- ES6,而我们等待它发生(或其中一些)
- 出色的 IDE 支持来执行所有这些魔法
TypeScript 似乎是解决我的问题的完美解决方案,但我的 Web 应用程序太大太复杂,无法以大包方式重写为 TypeScript。我必须采用增量方法并承诺使用 TypeScript 编写所有新代码,同时将旧代码保留在 JavaScript 中。 TypeScript 和 JavaScript 的这种可互换使用导致了一些问题,这些问题需要记录不完整的 TypeScript 功能,我将在这篇博文中对此进行描述。
对于喜欢检查源代码并跳过阅读的人:https: //github.com/v3nom/RequireJStoTypescript
从 JavaScript (AMD) 使用 TypeScript
从 JavaScript 使用 TypeScript 代码非常简单。使用 AMD 模块格式编译 Typescript 源代码。生成的 JavaScript 默认放在 TypeScript 文件旁边,到目前为止,这个设置对我来说效果最好。
查看新的 tsconfig.json 功能( 阅读更多 )。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
我们要在现有 JavaScript 代码中使用的 TypeScript 类。类必须作为模块导出(TS 1.4 中的外部模块)。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
简单的 JavaScript 模块。我们希望 JavaScript 文件是在与 TypeScript 源代码相同的位置生成的,因此在声明 AMD 依赖项时我们真的不需要考虑它。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
从 TypeScript 使用现有的 JavaScript AMD
现在这就是事情变得有点棘手的地方。为了导入 JavaScript 代码,我们需要使用引用注释。
我们要在 TypeScript 代码中使用的 JavaScript 模块。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
这是一个使用遗留 JavaScript 代码的 TypeScript 文件。参考注释必须是 TypeScript 文件中的第一件事(陷阱)。您基本上是在 AMD 定义何时生成 JavaScript 代码时编写要填充的内容: 路径 是依赖项位置, 名称 是您可以引用导入的依赖项的名称。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
编译后的 JS 代码最好地解释了发生了什么。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
奖励:遗留 JavaScript 代码的类型支持(手动)
如果您有空闲时间来声明类型定义,您还可以在 TypeScript 中对遗留 JavaScript 代码进行类型检查。
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
现在我们可以简化我们之前的 TypeScript 类
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
将生成完全相同的 JavaScript 代码。如果您在项目中遇到名称冲突问题,您还可以更新旧版本:
//tsconfig.json
...
"compilerOptions": {
"module": "amd",
}
...
结论
将企业 Web 应用程序增量更新为 TypeScript 轻而易举。每次我接触旧版 JavaScript 代码时,我都会将其转换为 TypeScript。而且由于 JavaScript 是合法的 TypeScript,因此引入新错误的可能性非常小。但是,当然,单元测试在任何大项目中都是必须的。
从现在开始,所有新的客户端代码都是用 TypeScript 编写的,并且很容易让其他团队成员参与进来。