

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# `APPSYNC_JS` 執行時間的綁定、TypeScript 和來源映射
<a name="additional-utilities"></a>

TypeScript 透過提供類型安全和早期錯誤偵測來增強 AWS AppSync 開發。您可以在本機撰寫 TypeScript 程式碼並將其轉換為 JavaScript，然後再與`APPSYNC_JS`執行時間搭配使用。程序從安裝 TypeScript 和為`APPSYNC_JS`環境設定 tsconfig.json 開始。然後，您可以使用 esbuild 等綁定工具來編譯和綁定程式碼。Amplify CLI 會從 GraphQL 結構描述產生類型，讓您可以在解析程式程式碼中使用這些類型。

只要符合`APPSYNC_JS`要求，您就可以在解析程式和函數程式碼中利用自訂和外部程式庫。綁定工具將程式碼合併為單一檔案以供使用 AWS AppSync。可以包含來源映射以協助偵錯。

## 利用程式庫並綁定程式碼
<a name="using-external-libraries"></a>

在解析程式和函數程式碼中，只要符合`APPSYNC_JS`要求，您就可以利用自訂程式庫和外部程式庫。這可讓您在應用程式中重複使用現有的程式碼。若要使用由多個檔案定義的程式庫，您必須使用綁定工具，例如 [esbuild](https://esbuild.github.io/)，將程式碼合併到單一檔案中，然後儲存到 AWS AppSync 解析程式或函數。

綁定程式碼時，請記住下列事項：
+ `APPSYNC_JS` 僅支援 ECMAScript 模組 (ESM)。
+ `@aws-appsync/*` 模組已整合至 `APPSYNC_JS` ，且不應與您的程式碼綁定。
+ `APPSYNC_JS` 執行時間環境類似於 NodeJS，因為該程式碼不會在瀏覽器環境中執行。
+ 您可以包含選用的來源映射。不過，請勿包含來源內容。

  若要進一步了解來源映射，請參閱[使用來源映射](#source-maps)。

例如，若要綁定位於 的解析程式程式碼`src/appsync/getPost.resolver.js`，您可以使用下列 esbuild CLI 命令：

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/getPost.resolver.js
```

## 建置程式碼並使用 TypeScript
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/) 是由 Microsoft 開發的一種程式設計語言，可提供 JavaScript 的所有功能以及 TypeScript 類型系統。您可以使用 TypeScript 撰寫安全類型的程式碼，並在建置時擷取錯誤和錯誤，再將程式碼儲存至 AWS AppSync。`@aws-appsync/utils` 套件已完全輸入。

`APPSYNC_JS` 執行時間不支援 TypeScript。您必須先將 TypeScript 程式碼轉換為`APPSYNC_JS`執行時間支援的 JavaScript 程式碼，才能將程式碼儲存到其中 AWS AppSync。您可以使用 TypeScript 在本機整合開發環境 (IDE) 中撰寫程式碼，但請注意，您無法在 AWS AppSync 主控台中建立 TypeScript 程式碼。

若要開始使用，請確定專案中已安裝 [TypeScript](https://www.typescriptlang.org/download)。然後，設定 TypeScript 轉編譯設定，以使用 [TSConfig](https://www.typescriptlang.org/tsconfig) 搭配`APPSYNC_JS`執行時間。以下是您可以使用的基本`tsconfig.json`檔案範例：

```
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   "noEmit": true,
   "moduleResolution": "node",
  }
}
```

然後，您可以使用 esbuild 等綁定工具來編譯和綁定程式碼。例如，假設專案的 AWS AppSync 程式碼位於 `src/appsync`，您可以使用下列命令來編譯和綁定程式碼：

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/**/*.ts
```

### 使用 Amplify codegen
<a name="working-with-amplify-codegen"></a>

您可以使用 [Amplify CLI](https://docs.amplify.aws/cli/) 來產生結構描述的類型。從`schema.graphql`檔案所在的目錄中，執行下列命令並檢閱提示以設定您的 Codegen：

```
$  npx @aws-amplify/cli codegen add
```

若要在某些情況下 （例如，結構描述更新時） 重新產生您的程式碼，請執行下列命令：

```
$ npx @aws-amplify/cli codegen
```

然後，您可以在解析程式程式碼中使用產生的類型。例如，指定下列結構描述：

```
type Todo {
  id: ID!
  title: String!
  description: String
}

type Mutation {
  createTodo(title: String!, description: String): Todo
}

type Query {
  listTodos: Todo
}
```

您可以在下列範例 AWS AppSync 函數中使用產生的類型：

```
import { Context, util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'
import { CreateTodoMutationVariables, Todo } from './API' // codegen

export function request(ctx: Context<CreateTodoMutationVariables>) {
	ctx.args.description = ctx.args.description ?? 'created on ' + util.time.nowISO8601()
	return ddb.put<Todo>({ key: { id: util.autoId() }, item: ctx.args })
}

export function response(ctx) {
	return ctx.result as Todo
}
```

### 在 TypeScript 中使用通用
<a name="working-with-typescript-generics"></a>

您可以搭配多種提供的類型使用學名藥。例如，以下程式碼片段是一種`Todo`類型：

```
export type Todo = {
  __typename: "Todo",
  id: string,
  title: string,
  description?: string | null,
};
```

您可以為使用 的訂閱撰寫解析程式`Todo`。在您的 IDE 中，輸入定義和自動完成提示將引導您正確使用`toSubscriptionFilter`轉換公用程式：

```
import { util, Context, extensions } from '@aws-appsync/utils'
import { Todo } from './API'

export function request(ctx: Context) {
  return {}
}

export function response(ctx: Context) {
  const filter = util.transform.toSubscriptionFilter<Todo>({
    title: { beginsWith: 'hello' },
    description: { contains: 'created' },
  })
  extensions.setSubscriptionFilter(filter)
  return null
}
```

## 內嵌您的套件
<a name="using-lint-with-bundles"></a>

您可以透過匯入 `esbuild-plugin-eslint` 外掛程式自動繫結套件。然後，您可以提供啟用隱含功能`plugins`的值來啟用它。以下是在名為 的檔案中使用 esbuild JavaScript API 的程式碼片段`build.mjs`：

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

## 使用來源映射
<a name="source-maps"></a>

您可以使用 JavaScript 程式碼提供內嵌來源映射 (`sourcemap`)。當您綁定 JavaScript 或 TypeScript 程式碼，並想要在日誌和執行時間 JavaScript 錯誤訊息中查看對輸入來源檔案的參考時，來源映射非常有用。

您的 `sourcemap` 必須出現在程式碼的結尾。它由遵循下列格式的單一註解行定義：

```
//# sourceMappingURL=data:application/json;base64,<base64 encoded string>
```

範例如下：

```
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliLmpzIiwgImNvZGUuanMiXSwKICAibWFwcGluZ3MiOiAiO0FBQU8sU0FBUyxRQUFRO0FBQ3RCLFNBQU87QUFDVDs7O0FDRE8sU0FBUyxRQUFRLEtBQUs7QUFDM0IsU0FBTyxNQUFNO0FBQ2Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
```

您可以使用 esbuild 建立來源映射。以下範例說明如何在建置和綁定程式碼時，使用 esbuild JavaScript API 來包含內嵌來源映射：

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  sourcemap: 'inline',
  sourcesContent: false,
  
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

特別是， `sourcemap`和 `sourcesContent`選項指定應該在每個組建結束時逐行新增來源映射，但不應包含來源內容。作為慣例，我們建議您不要在 中包含來源內容`sourcemap`。您可以將 `sources-content`設定為 ，在 esbuild 中停用此功能`false`。

若要說明來源映射的運作方式，請檢閱下列解析程式程式碼參考協助程式程式庫中協助程式函數的範例。此程式碼包含解析程式程式碼和協助程式程式程式庫中的日誌陳述式：

**./src/default.resolver.ts** （您的解析程式）

```
import { Context } from '@aws-appsync/utils'
import { hello, logit } from './helper'

export function request(ctx: Context) {
  console.log('start >')
  logit('hello world', 42, true)
  console.log('< end')
  return 'test'
}

export function response(ctx: Context): boolean {
  hello()
  return ctx.prev.result
}
```

**.src/helper.ts** （協助程式檔案）

```
export const logit = (...rest: any[]) => {
  // a special logger
  console.log('[logger]', ...rest.map((r) => `<${r}>`))
}

export const hello = () => {
  // This just returns a simple sentence, but it could do more.
  console.log('i just say hello..')
}
```

當您建置和綁定解析程式檔案時，您的解析程式程式碼將包含內嵌來源映射。當您的解析程式執行時，以下項目會出現在 CloudWatch 日誌中：

![\[CloudWatch log entries showing resolver code execution with inline source map information.\]](http://docs.aws.amazon.com/zh_tw/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


查看 CloudWatch 日誌中的項目，您會注意到這兩個檔案的功能已綁定在一起並同時執行。每個檔案的原始檔案名稱也會清楚地反映在日誌中。