Skip to content

Cloudflare Workers

Cloudflare Workers는 Cloudflare CDN 위에서 동작하는 JavaScript 엣지 런타임이다.

Wrangler를 사용하면 로컬에서 애플리케이션을 개발하고 몇 가지 커맨드로 배포할 수 있다. Wrangler는 트랜스컴파일러를 포함하고 있어 TypeScript로 코드를 작성할 수 있다.

Hono를 사용해 Cloudflare Workers의 첫 번째 애플리케이션을 만들어 보자.

1. 설정

Cloudflare Workers를 위한 스타터 프로젝트를 사용할 수 있다. create-hono 커맨드로 프로젝트를 시작한다. 이 예제에서는 cloudflare-workers 템플릿을 선택한다.

sh
npm create hono@latest my-app
sh
yarn create hono my-app
sh
pnpm create hono my-app
sh
bun create hono@latest my-app
sh
deno init --npm hono my-app

my-app 디렉터리로 이동한 후 의존성을 설치한다.

sh
cd my-app
npm i
sh
cd my-app
yarn
sh
cd my-app
pnpm i
sh
cd my-app
bun i

2. Hello World

src/index.ts 파일을 아래와 같이 수정한다.

ts
import { Hono } from 'hono'
const app = new Hono()

app.get('/', (c) => c.text('Hello Cloudflare Workers!'))

export default app

3. 실행

로컬에서 개발 서버를 실행한다. 그런 다음 웹 브라우저에서 http://localhost:8787에 접속한다.

sh
npm run dev
sh
yarn dev
sh
pnpm dev
sh
bun run dev

포트 번호 변경하기

포트 번호를 변경해야 한다면, wrangler.toml / wrangler.json / wrangler.jsonc 파일을 업데이트하는 방법을 참고할 수 있다. 자세한 내용은 다음 링크를 확인한다: Wrangler 설정

또는 CLI 옵션을 설정하는 방법도 있다. 다음 링크에서 자세한 안내를 확인할 수 있다: Wrangler CLI

4. 배포

Cloudflare 계정이 있다면 Cloudflare에 배포할 수 있다. package.json에서 $npm_execpath를 사용할 패키지 관리자에 맞게 변경해야 한다.

sh
npm run deploy
sh
yarn deploy
sh
pnpm run deploy
sh
bun run deploy

이것으로 끝이다!

서비스 워커 모드와 모듈 워커 모드

Cloudflare Workers를 작성하는 데는 두 가지 구문이 있다. 바로 모듈 워커 모드서비스 워커 모드다. Hono를 사용하면 두 구문 모두로 작성할 수 있지만, 바인딩 변수를 지역화할 수 있는 모듈 워커 모드를 사용하는 것을 권장한다.

ts
// 모듈 워커
export default app
ts
// 서비스 워커
app.fire()

Hono를 다른 이벤트 핸들러와 함께 사용하기

_Module Worker 모드_에서 Hono를 scheduled와 같은 다른 이벤트 핸들러와 통합할 수 있다.

이를 위해 모듈의 fetch 핸들러로 app.fetch를 내보내고, 필요에 따라 다른 핸들러를 구현한다:

ts
const app = new Hono()

export default {
  fetch: app.fetch,
  scheduled: async (batch, env) => {},
}

정적 파일 제공하기

정적 파일을 제공하려면 Cloudflare Workers의 정적 에셋 기능을 사용한다. wrangler.toml 파일에서 파일이 위치한 디렉토리를 지정한다:

toml
assets = { directory = "public" }

이후 public 디렉토리를 생성하고 파일을 해당 위치에 배치한다. 예를 들어, ./public/static/hello.txt 파일은 /static/hello.txt 경로로 제공된다.

.
├── package.json
├── public
│   ├── favicon.ico
│   └── static
│       └── hello.txt
├── src
│   └── index.ts
└── wrangler.toml

타입

워커 타입을 사용하려면 @cloudflare/workers-types를 설치해야 한다.

sh
npm i --save-dev @cloudflare/workers-types
sh
yarn add -D @cloudflare/workers-types
sh
pnpm add -D @cloudflare/workers-types
sh
bun add --dev @cloudflare/workers-types

테스트

테스트를 위해 @cloudflare/vitest-pool-workers를 사용할 것을 권장한다. 설정 방법은 예제를 참고한다.

아래와 같은 애플리케이션이 있다고 가정하자.

ts
import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Please test me!'))

이 애플리케이션이 "200 OK" 응답을 반환하는지 다음과 같이 테스트할 수 있다.

ts
describe('애플리케이션 테스트', () => {
  it('200 응답을 반환해야 함', async () => {
    const res = await app.request('http://localhost/')
    expect(res.status).toBe(200)
  })
})

바인딩

Cloudflare Workers에서는 환경 변수, KV 네임스페이스, R2 버킷, 또는 Durable Object를 바인딩할 수 있다. c.env를 통해 이들에 접근할 수 있다. Hono에 제네릭으로 바인딩에 대한 "타입 구조체"를 전달하면 타입 정보를 갖게 된다.

ts
type Bindings = {
  MY_BUCKET: R2Bucket
  USERNAME: string
  PASSWORD: string
}

const app = new Hono<{ Bindings: Bindings }>()

// 환경 변수에 접근
app.put('/upload/:key', async (c, next) => {
  const key = c.req.param('key')
  await c.env.MY_BUCKET.put(key, c.req.body)
  return c.text(`Put ${key} successfully!`)
})

미들웨어에서 변수 사용하기

이 사례는 Module Worker 모드에서만 적용된다. 예를 들어 Basic Authentication 미들웨어에서 "username"이나 "password"와 같은 변수나 시크릿 변수를 사용하려면 다음과 같이 작성해야 한다.

ts
import { basicAuth } from 'hono/basic-auth'

type Bindings = {
  USERNAME: string
  PASSWORD: string
}

const app = new Hono<{ Bindings: Bindings }>()

//...

app.use('/auth/*', async (c, next) => {
  const auth = basicAuth({
    username: c.env.USERNAME,
    password: c.env.PASSWORD,
  })
  return auth(c, next)
})

이 방법은 Bearer Authentication 미들웨어, JWT 인증 등 다른 미들웨어에도 동일하게 적용된다.

GitHub Actions로 배포하기

CI를 통해 Cloudflare에 코드를 배포하기 전에 Cloudflare 토큰이 필요하다. User API Tokens에서 토큰을 관리할 수 있다.

새로 토큰을 생성한다면 Edit Cloudflare Workers 템플릿을 선택한다. 이미 다른 토큰이 있다면, 해당 토큰에 적절한 권한이 있는지 확인한다(Cloudflare Pages와 Cloudflare Workers 간에 토큰 권한은 공유되지 않는다).

그다음 GitHub 저장소 설정 대시보드로 이동한다: Settings->Secrets and variables->Actions->Repository secrets. 여기서 CLOUDFLARE_API_TOKEN이라는 이름으로 새로운 시크릿을 추가한다.

이제 Hono 프로젝트 루트 폴더에 .github/workflows/deploy.yml 파일을 생성하고 다음 코드를 붙여넣는다:

yml
name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

그리고 wrangler.toml 파일을 편집해 compatibility_date 라인 뒤에 다음 코드를 추가한다:

toml
main = "src/index.ts"
minify = true

이제 모든 준비가 끝났다. 코드를 푸시하고 배포를 즐겨보자.

로컬 개발 시 환경 변수 설정하기

로컬 개발을 위한 환경 변수를 설정하려면 프로젝트 루트 디렉터리에 .dev.vars 파일을 생성한다. 일반적인 env 파일과 동일한 방식으로 환경 변수를 설정하면 된다.

SECRET_KEY=value
API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

이 섹션에 대한 자세한 내용은 Cloudflare 문서에서 확인할 수 있다: https://developers.cloudflare.com/workers/wrangler/configuration/#secrets

코드에서 환경 변수를 가져오려면 c.env.*를 사용한다.
Cloudflare Workers에서는 process.env가 아닌 c를 통해 환경 변수를 가져와야 한다.

ts
type Bindings = {
  SECRET_KEY: string
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/env', (c) => {
  const SECRET_KEY = c.env.SECRET_KEY
  return c.text(SECRET_KEY)
})

프로젝트를 Cloudflare에 배포하기 전에, Cloudflare Workers 프로젝트 설정에서 환경 변수/시크릿을 설정해야 한다.

이 섹션에 대한 자세한 내용은 Cloudflare 문서에서 확인할 수 있다: https://developers.cloudflare.com/workers/configuration/environment-variables/#add-environment-variables-via-the-dashboard

Released under the MIT License.