我以前写过有关如何实施dynamic redirect mechanism for Azure Static Web Apps using Azure Functions的文章。我使用JSDOC JavaScript实施了此功能。从那以后,我将其迁移到Typescript,我认为分享该过程很有趣。
为什么要从JSDOC JavaScript迁移到打字稿?
正如普通读者所知道的那样,我既是打字稿的忠实拥护者,又是JSDOC JavaScript的忠实拥护者。我认为两者都很棒。那么,为什么要从JSDOC JavaScript迁移到打字稿呢?对我来说,这主要是关于开发人员的体验; JSDOC的详细性更大,并且更广泛的生态系统比JSDOC JavaScript所做的打字率要多得多。因此,当您超越简单应用程序时,至少对我来说,Typescript是一个更好的选择。
My blog是一个具有Azure函数后端的Azure Static Web App。我一直在使用JSDOC JavaScript来完成我的Azure功能。这篇文章将带来后端并将其迁移到打字稿。我已经有各种各样的能力,我不想沿途失去:
- 我可以在VS代码中调试
- 我使用github操作部署
- 我使用开玩笑进行了自动测试
所有这些负担能力都可以通过打字稿提供,我想保留它们。让我们开始迁移。顺便说一下,此迁移的代码lies in this PR。
迁移tsconfig.json
我们的tsconfig.json
管理打字稿编译器与我们的代码交互的方式。我们将从迁移开始:
```d diff title =“ tsconfig.json”
{
“ compileroptions”:{
- “ noemit”:true,
- “ noemit”:false,
- “ oftdir”:“ dist”,
- “ rootdir”:“。”,
-
“ sourcemap”:true,
-
“ allyjs”:false, p> li>
-
“ checkjs”:false,
-
“ moduleresolution”:“ node”,
}
}
让我们看一下我们所做的更改:
- 由于
noEmit
设置为false
,我们现在从编译中发出文件。我们将不再实际运行我们编写的代码,但是我们将运行我们发出的JavaScript。 - 我们正在指定
dist
的outDir
-这是我们编译的JavaScript发出的地方。 - 我们正在指定
.
的rootDir
-这是我们的打字稿源文件的根。 - 我们正在为发射的JavaScript文件创建源地图 - 这将有助于我们调试原始源代码。 (即使我们没有运行它。)
- 由于将
allowJs
设置为false
,我们不再允许JavaScript文件成为我们程序的一部分。 (而且,由于将checkJs
设置为false
,我们也不会检查它们 - 我怀疑这是隐式设置为false
toallowJs
为false
-要清楚,我已经指定了它。) )
- 我们正在指定
node
的moduleResolution
-这是打字稿将如何从给定模块指定器查找文件。
迁移package.json
要迁移我们的package.json
,我们需要添加一些依赖项并调整我们的脚本:
“脚本”:{
“构建”:“ TSC”,
- “观看”:“ TSC -W”,
- “ prestart”:“ npm run build”, “开始”:“ func start”, “测试”:“ IS” },, “ devDectiencies”:{ “@azure/functions”:“^3.5.0”,
- “@type/is”:“^29.2.5”,
- “@type/node”:“^18.x”, “是”:“^29.3.1”,
- “ ts-is”:“^29.1.0”, “打字稿”:“^5.0.0” } } ````````
我们正在添加两个脚本:
-
watch
-这将观看我们的打字稿文件并在更改时重新编译它们 - 我们真的不需要;但这取决于您喜欢的工作流程。 -
prestart
-这将在start
之前运行,并确保我们的打字稿文件已编译,并且我们有最新的JavaScript运行。
在我们的devDependencies
中,我们正在为jest and node.js添加依赖项。我们还添加了ts-jest
,这将使我们能够运行用打字稿编写的开玩笑测试。
迁移.vscode/settings.json
和.vscode/tasks.json
我较早提到了调试 - 要使该调试到位,我们需要在.vscode
文件夹中的settings.json
和tasks.json
文件上工作。首先是settings.json
:
```d diff title =“ settings .json”
- “ azurefunctions.projectlanguage”:“ javascript”,
- “ azurefunctions.projectlanguage”:“ typescript”, ````````
以上是自我解释的。我们正在将Azure功能项目的语言从JavaScript更改为打字稿。现在tasks.json
:
```d diff title =“ tasks.json”
{
“版本”:“ 2.0.0”,
“任务”:[
- {
- “ type”:“ shell”,
- “ label”:“ npm build(functions)”,
- “命令”:“ npm run构建”,
- “ deverson”:“ npm install(functions)”,
- “ QuessionMatcher”:“ $ tsc”,
- “选项”:{
- “ cwd”:“ $ {workspacefolder}/blog-website/api”
- }, 这是给出的 } ````````
我们在这里有一个新的任务,可以运行我们的npm run build
脚本。这将把我们的打字稿文件编译到JavaScript。我们还将cwd
设置为blog-website/api
-这是我们的Azure函数使用的文件夹 - 您自己可能会有所不同。除了这个新脚本外,现有任务有一些调整,以使其取决于我们的新构建任务:
```d diff title =“ tasks.json”
{
“版本”:“ 2.0.0”,
“任务”:[
{
“ type”:“ func”,
“ label”:“ func:主机开始”,
“命令”:“主机开始”,
“ QuessionMatcher”:“ $ func-node-watch”,
“ isbackground”:true,
- “依赖森”:“ npm build(functions)”,
- “选项”:{
- “ cwd”:“ $ {workspacefolder}/blog-website/api”
- } },, // ... { “ type”:“ shell”, “ label”:“ npm Prune(函数)”, “命令”:“ NPM Prune-生产”,
- “依赖森”:“ npm构建(functions)”, “ QuessionMatcher”:[], “选项”: { “ cwd”:“ $ {workspacefolder}/blog-website/api” } } 这是给出的 } ````````
迁移我们的Azure功能
这将不会成为从JSDOC JavaScript迁移到打字稿的详尽指南。我将专注于发现与Azure功能最相关的内容。让我们从fallback/function.json
文件开始,该文件为我们的动态重定向供电,并生活在/api/fallback
:
{
“绑定”:[
{
“ authlevel”:“匿名”,
“ type”:“ httptrigger”,
“方向”:“在”,
“名称”:“ req”,
“方法”:[“ get”,“ post”]
},
{
“ type”:“ http”,
“方向”:“ out”,
“名称”:“ res”
}
],
- “ scriptfile”:“ ../ dist/fallback/index.js” } ````````
这里有一个增加,将scriptFile
重新分配到编译的JavaScript。
现在让我们看一下该功能的代码。最初是名为index.js
的JavaScript文件;必须将其重命名为index.ts
。原始代码看起来像这样:
```js title =“ flastback/index.js”
const redirect = require('./ redirect');
const savetodatabase = require('./ savetodatabase');
/**
*
- @param {import(“@azure/functions”)。上下文}上下文
- @param {import(“@azure/functions”)。httprequest} req */ 异步函数afflack(context,req){ // ... }
module.exports = hallback;
After renaming to `index.ts` and adding some TypeScript types, it looks like this:
```ts title="fallback/index.ts"
import type { AzureFunction, Context, HttpRequest } from '@azure/functions';
import { redirect } from './redirect';
import { saveToDatabase } from './saveToDatabase';
const httpTrigger: AzureFunction = async function (
context: Context,
req: HttpRequest
): Promise<void> {
//...
};
export default httpTrigger;
我们可以看到,导入的类型变得更加简洁。我们还将该功能导出为default
而不是module.exports
。这是因为我们使用ES模块而不是CommonJS模块进行创作。我们还可以看到,我们使用import
而不是require
来导入我们的功能。虽然CONCORJS更为简单,但ES模块的语法感觉更加更好。至少对我来说。 (值得注意的是,我们不在编译的JavaScript中使用ES模块 - 我们仍在使用CommonJ;但是当我们编写代码时,我们不需要考虑一下。)
我不会浏览其他文件,但是该过程是相同的。将文件重命名为.ts
,添加打字稿类型,然后使用import
而不是require
。
迁移我们的测试
我们现在几乎在家中;我们只需要迁移测试即可。让我们从jest.config.js
开始:
```d diff title =“ jest.config.js”
- 预设:'ts-stest',
- TESTPATHIGNOREPATTERNS:['/node_modules/','/dist/'], ````````
我们正在添加ts-jest
的preset
,这将使我们能够运行打字稿测试。如果您还记得,我们较早添加了ts-jest
依赖性;就是这样。
我们还将dist
添加到我们的testPathIgnorePatterns
-这是因为我们不想对我们编译的JavaScript进行测试 - 我们最终将两次运行测试。
让我们将注意力直接转移到测试上。同样,我们从.js
到.ts
进行了经典的重命名,我们的进口变成了简短的ES模块Y:
```d diff title =“ redirect.test.ts”
- /**
- * @typedef {import(“@azure/functions”)。logger} logger
- */ +来自'@azure/functions'的导入类型{logger}; -const {描述,期望,测试} = require('@jest/globals'); +导入{描述,期望,测试}来自'@jest/globals'; -const redirect = require('./ redirect'); +来自'./redirect'的导入{redirect}; ````````
美丽。最后,我们对测试本身的代码进行了一些调整。首先,声明我们的模拟变得容易得多:
```d diff title =“ redirect.test.ts”
- / ** @Type {is.mock}*/ const ockklogger = is.fn();
+const ocorlogger:is.mock = is.fn();
Secondly, casting our mock to the type we want is much more straightforward:
```diff title="redirect.test.ts"
-/** @type {any} */ (mockLogger)
+mockLogger as unknown as Logger
我没有真实的方式如何在JSDOC中两次铸造 - 现在我不需要。
结论
我们现在有一个打字稿Azure函数代码库,并提供我们之前拥有的所有调试 /测试 /部署。我们不必在部署方面做任何事情,因为它只是效果。我希望这篇文章对您有用!