Cloudflare Workers

Cloudflare Workers بيئة تشغيل JavaScript على الحافة (edge) في Cloudflare CDN.

يمكنك تطوير التطبيق محليًا ونشره بأوامر قليلة باستخدام Wrangler. يتضمن Wrangler محوّل شفرة (transcompiler)، لذا يمكننا كتابة الكود بلغة TypeScript.

لننشئ تطبيقك الأول لـ Cloudflare Workers باستخدام Hono.

1. الإعداد

يتوفر قالب بداية لـ Cloudflare Workers. ابدأ مشروعك باستخدام الأمر "create-hono". اختر cloudflare-workers قالب لهذا المثال.

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

انتقل إلى my-app وثبّت التبعيات.

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

2. مرحبًا بالعالم

تعديل src/index.ts كما هو موضح أدناه.

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

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

export default app

3. تشغيل

شغّل خادم التطوير محليًا. ثم، ادخل إلى http://localhost:8787 في متصفح الويب الخاص بك.

npm run dev
yarn dev
pnpm dev
bun run dev

تغيير رقم المنفذ

إذا كنت بحاجة إلى تغيير رقم المنفذ، يمكنك اتباع التعليمات هنا لتحديث wrangler.toml / wrangler.json / wrangler.jsonc files: إعداد Wrangler

أو، يمكنك اتباع التعليمات هنا لضبط خيارات CLI: Wrangler CLI

4. النشر

إذا كان لديك حساب Cloudflare، يمكنك النشر على Cloudflare. في package.json, $npm_execpath يجب تغييره إلى مدير الحزم (package manager) الذي تختاره.

npm run deploy
yarn deploy
pnpm run deploy
bun run deploy

هذا كل شيء!

استخدام Hono مع معالجات أحداث أخرى

يمكنك دمج Hono مع معالجات أحداث (event handlers) أخرى (مثل scheduled) في وضع Module Worker.

لفعل ذلك، صدّر app.fetch كخاصية للوحدة fetch المعالج، ثم نفّذ المعالجات الأخرى حسب الحاجة:

const app = new Hono()

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

تقديم الملفات الثابتة

إذا أردت تقديم ملفات ثابتة، يمكنك استخدام ميزة الأصول الثابتة (Static Assets) الخاصة بـ Cloudflare Workers. حدِّد دليل الملفات في wrangler.jsonc:

"assets": { "directory": "public" }

ثم أنشئ public الدليل وضع الملفات هناك. على سبيل المثال، ./public/static/hello.txt سيُقدَّم كـ /static/hello.txt.

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

الأنواع

يجب عليك تثبيت @cloudflare/workers-types إذا كنت تريد الحصول على أنواع workers.

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

الاختبار

للاختبار، نوصي باستخدام @cloudflare/vitest-pool-workers. راجع أمثلة لإعداده.

إذا كان هناك التطبيق أدناه.

import { Hono } from 'hono'

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

يمكننا اختبار ما إذا كانت تُعيد استجابة "200 OK" بهذا الكود.

describe('Test the application', () => {
  it('Should return 200 response', async () => {
    const res = await app.request('http://localhost/')
    expect(res.status).toBe(200)
  })
})

الارتباطات

في Cloudflare Workers، يمكننا ربط قيم البيئة، أو مساحة أسماء KV namespace، أو حاوية R2 bucket، أو كائن Durable Object. يمكنك الوصول إليها في c.env. ستمتلك الأنواع (types) إذا مررت "تعريف النوع" للارتباطات (bindings) إلى Hono كأنواع عامة.

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

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

// Access to environment values
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!`)
})

توليد أنواع الارتباطات (Bindings) تلقائيًا

بدلًا من تعريف أنواع الروابط (bindings) يدويًا، يمكنك توليدها تلقائيًا من wrangler.toml باستخدام wrangler types الأمر. استخدم --env-interface العلم لتجنب تعارض في التسمية مع المدمج في Hono Env type:

wrangler types --env-interface CloudflareBindings

يولِّد هذا worker-configuration.d.ts ملف باسم الواجهة (interface) الذي تحدِّده. ثم مرِّره إلى Hono:

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

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. إذا كنت تريد استخدام المتغيرات (Variables) أو المتغيرات السرية (Secret Variables) في الوسائط، على سبيل المثال، "username" أو "password" في وسيط المصادقة الأساسية (Basic Authentication Middleware)، فأنت بحاجة إلى الكتابة كما يلي.

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 ووسيطة مصادقة JWT، أو غيرها.

النشر من GitHub Actions

قبل نشر الكود إلى Cloudflare عبر CI، تحتاج إلى رمز مميز خاص بـ Cloudflare. يمكنك إدارته من رموز API للمستخدم.

إذا كان رمزًا (token) تم إنشاؤه حديثًا، فحدد قالب Edit Cloudflare Workers. إذا كان لديك بالفعل رمز آخر، تأكد من أن الرمز لديه الأذونات المقابلة.

ثم انتقل إلى لوحة إعدادات مستودعك على GitHub: Settings->Secrets and variables->Actions->Repository secrets، وأضف سرًّا جديدًا بالاسم CLOUDFLARE_API_TOKEN.

ثم أنشئ .github/workflows/deploy.yml في مجلد جذر مشروع Hono الخاص بك، الصق الكود التالي:

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.jsonc، وأضف هذا الرمز بعد compatibility_date سطر.

"main": "src/index.ts",
"minify": true

كل شيء جاهز! الآن ادفع الشفرة واستمتع بها.

تحميل متغيرات البيئة أثناء التطوير المحلي

لتكوين متغيرات البيئة (environment variables) للتطوير المحلي، أنشئ ملف .dev.vars ملف أو .env ملف في الدليل الجذر للمشروع. يجب تنسيق هذه الملفات باستخدام dotenv الصياغة. على سبيل المثال:

SECRET_KEY=value
API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

لمزيد من المعلومات حول هذا القسم، يمكنك مراجعة توثيق Cloudflare: https://developers.cloudflare.com/workers/wrangler/configuration/#secrets

ثم نستخدم c.env.* للحصول على متغيّرات البيئة في شفرتنا.

بشكل افتراضي، process.env غير متاح في Cloudflare Workers، لذا يُنصح بالحصول على متغيرات البيئة من c.env. إذا أردت استخدامه، فيجب عليك تمكين nodejs_compat_populate_process_env العلم. يمكنك أيضًا استيراد env من cloudflare:workers. لمزيد من التفاصيل، يُرجى الاطلاع على كيفية الوصول إلى env في وثائق Cloudflare

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، تذكر تعيين متغيرات البيئة/الأسرار (secrets) في إعداد مشروع Cloudflare Workers.

لمزيد من المعلومات حول هذا القسم، يمكنك مراجعة توثيق Cloudflare: https://developers.cloudflare.com/workers/configuration/environment-variables/#add-environment-variables-via-the-dashboard