

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# `APPSYNC_JS` 런타임용 번들링, TypeScript 및 소스 맵
<a name="additional-utilities"></a>

TypeScript는 유형 안전 및 조기 오류 감지를 제공하여 AWS AppSync 개발을 개선합니다. TypeScript 코드를 `APPSYNC_JS` 런타임에 사용하기 전에 로컬로 작성하고 JavaScript로 트랜스파일할 수 있습니다. 이 프로세스는 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에서 개발한 프로그래밍 언어로, TypeScript 타이핑 시스템과 함께 JavaScript의 모든 기능을 제공합니다. TypeScript를 사용하여 type-safe 코드를 작성하고 코드를 AWS AppSync에 저장하기 전에 빌드 시 오류와 버그를 잡을 수 있습니다. `@aws-appsync/utils` 패키지가 완전히 입력되었습니다.

`APPSYNC_JS` 런타임은 TypeScript를 직접 지원하지 않습니다. 코드를 AWS AppSync에 저장하기 전에 먼저 TypeScript 코드를 `APPSYNC_JS` 런타임이 지원하는 JavaScript 코드로 변환해야 합니다. TypeScript를 사용하여 로컬 통합 개발 환경(IDE)에서 코드를 작성할 수 있지만 AWS AppSync 콘솔에서는 TypeScript 코드를 생성할 수 없습니다.

시작하려면 프로젝트에 [TypeScript](https://www.typescriptlang.org/download)가 설치되어 있는지 확인하세요. 그런 다음 [TSConfig](https://www.typescriptlang.org/tsconfig)를 사용하여 `APPSYNC_JS` 런타임에서 작동하도록 TypeScript 트랜스컴파일 설정을 구성합니다. 사용할 수 있는 기본 `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
```

특정 상황(예: 스키마 업데이트 시)에서 codegen을 재생성하려면 다음 명령을 실행합니다.

```
$ 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` 플러그인을 가져와서 번들을 자동으로 린트할 수 있습니다. 그런 다음 eslint 기능을 활성화하는 `plugins` 값을 제공하여 활성화할 수 있습니다. 아래는 `build.mjs`라는 파일에서 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({
  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`를 `false`로 설정하여 esbuild에서 이를 비활성화할 수 있습니다.

소스 맵의 작동 방식을 설명하려면 해석기 코드가 도우미 라이브러리의 도우미 함수를 참조하는 다음 예제를 검토하세요. 코드에는 해석기 코드와 도우미 라이브러리의 로그 명령문이 포함되어 있습니다.

**./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/ko_kr/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


CloudWatch 로그의 항목을 살펴보면 두 파일의 기능이 함께 번들로 묶여 동시에 실행되고 있음을 알 수 있습니다. 각 파일의 원본 파일 이름도 로그에 명확하게 반영됩니다.