البداية

تعلّم كيف تُنشئ مشروع Carats وتُشغّل تطبيقًا يُصيَّر على الخادم.

المتطلبات

يستخدم Carats Bun لإدارة الحزم وتشغيل خادم التطوير. يترجم Bun ملفات TSX أثناء التشغيل، لذا لا توجد خطوة ترجمة منفصلة أثناء التطوير. يعمل Node.js 20+ أيضًا لبناءات الإنتاج، لكن Bun هو المسار المدعوم.

بدء سريع

أسرع طريقة للبدء هي مُولِّد المشاريع الرسمي. فهو يكتب تطبيق Carats كاملًا يعمل، مع الأوجه (facets) والدوال الخادمية (culets) وتخطيط مشترك ورموز تصميم SASS واختبارات، بحيث تكون كل ميزة موصوفة في هذا التوثيق موصولة بالفعل ويمكن قراءتها كشيفرة عاملة.

أنشئ مشروعًا جديدًا

bun create carats my-carats-app
cd my-carats-app

يحل `bun create carats` الحزمة المنشورة `create-carats` ويشغّل ملفها التنفيذي `create-carats`، وهو ما يكتب مشروع Carats كاملًا في المجلد الذي تسمّيه. إذا لم تمرر اسم مجلد فسيُنشئ المشروع في المجلد الحالي.

ثبّت الاعتماديات وابدأ خادم التطوير

bun install
bun run dev

يستمع الخادم على `http://localhost:5173`. ويأتي المشروع المُولَّد مزوَّدًا بلوحة تحكم وسوق ومحفظة وصفحة تداول وتخطيط مشترك وصفحة غير موجودة وصفحة خطأ، لذا تكون كل ميزة موصوفة في هذا التوثيق موصولة بالفعل ويمكن قراءتها كشيفرة عاملة.

إعداد يدوي

إن كنت تفضّل البدء من مشروع فارغ، فأنشئ بنية المجلدات التالية وثبّت الاعتماديات بنفسك.

بنية المجلدات

أنشئ المجلدات والملفات التالية. المواضع ثابتة لأن الإطار يحلّها بالعرف.

src/
├── app.ts
├── vite-env.d.ts
├── dto/
│   ├── user.d.ts
│   └── trade-data.d.ts
├── client/
│   ├── index.html
│   ├── entrypoint.ts
│   ├── facets.tsx
│   ├── base.sass
│   ├── components/
│   │   ├── SearchInput.tsx
│   │   └── search-bar.sass
│   └── pages/
│       ├── _layout/index.tsx
│       ├── _error/index.tsx
│       ├── _not_found/index.tsx
│       ├── home/index.tsx
│       ├── market/index.tsx
│       ├── profile/index.tsx
│       └── trade/index.tsx
└── server/
    ├── entrypoint.ts
    └── culets.ts
public/
vite.config.client.ts
vite.config.server.ts
vitest.config.ts
tsconfig.json
package.json

تثبيت الاعتماديات

مقسَّم Carats إلى حزم صغيرة. اعتماديات التشغيل أدناه هي ما يستخدمه التطبيق المتكامل؛ أما اعتماديات التطوير فهي لازمة لترجمة JJSX ولـ SASS ولفحص الأنواع.

اعتماديات التشغيل

bun add @carats/core @carats/render @carats/hooks @carats/csr
bun add @carats/ssr @carats/express @carats/ssg
bun add express compression sirv

اعتماديات التطوير

bun add -d jjsx vite sass typescript
bun add -d @types/node @types/express @types/compression
bun add -d vitest @vitest/coverage-v8 @fetch-mock/vitest cross-env

تتطلب `@carats/express` إصدار Express 5، لذلك رقم الإصدار الرئيسي ليس اختياريًا.

الإعدادات

إعدادات TypeScript

يتطلب Carats ملف tsconfig.json في جذر المشروع. الخيارات types وjsx وjsxFactory وjsxFragmentFactory هي ما يُعلّم TypeScript لغة JJSX، أما typeRoots فهو ما يجعل واجهات DTO العامة في src/dto قابلة للحل.

{
  "compilerOptions": {
    "target": "es2022",
    "useDefineForClassFields": true,
    "module": "esnext",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "types": ["jjsx"],
    "typeRoots": ["./src/dto", "./node_modules"],
    "skipLibCheck": true,
    "jsx": "react",
    "jsxFactory": "JJSX.jsxFactory",
    "jsxFragmentFactory": "JJSX.fragmentFactory",

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src"]
}

يقوم `typeRoots` بعمليتين معًا. فهو يشير إلى `src/dto` ليُلتقط واجهات DTO العامة كملفات تعريف، ويُبقي `./node_modules` في مسار البحث ليُحل `types: ["jjsx"]`، لأن `jjsx` لا يقع ضمن `@types`.

إعدادات Vitize للعميل

يعمل بناء العميل في وضع الوسيط لأن خادم Express يملك مستمع HTTP. وتُعطِّل appType: 'custom' آلية الرجوع إلى HTML الخاصة بـ Vite، لأن Carats هو من يُصيّر قالب HTML بنفسه.

import { defineConfig } from 'vite'
import path from 'path'

export default defineConfig({
  publicDir: path.resolve(import.meta.dirname, 'public'),
  root: path.resolve(import.meta.dirname, 'src/client'),
  base: '/',
  appType: 'custom',
  server: {
    middlewareMode: true
  },
  build: {
    outDir: path.resolve(import.meta.dirname, 'dist/client'),
    emptyOutDir: true,
    manifest: true,
    minify: true,
    rollupOptions: {
      treeshake: true
    }
  }
})

إعدادات Vite للخادم

import { defineConfig } from 'vite'
import path from 'path'

export default defineConfig({
  publicDir: false,
  build: {
    ssr: path.resolve(__dirname, 'src/server/entrypoint.ts'),
    outDir: path.resolve(__dirname, 'dist/server'),
    emptyOutDir: true,
    minify: true,
    rollupOptions: {
      treeshake: true
    }
  }
})

سكربتات package.json

هذه السكربتات هي نقاط الدخول المدعومة للتطوير والبناء والمعاينة لتطبيق Carats.

{
  "scripts": {
    "dev": "bun --inspect=6499 src/app.ts",
    "build": "bun build:server && bun build:client",
    "build:client": "vite build --config vite.config.client.ts",
    "build:server": "vite build --config vite.config.server.ts",
    "build:static": "cross-env NODE_ENV=production carats-ssg",
    "preview": "cross-env NODE_ENV=production bun src/app.ts",
    "test": "vitest --run --coverage"
  }
}

يجب أن يكون ملف التطبيق الرئيسي في `src/app.ts`.

تشغيل التطبيق

يشغّل bun run dev التطبيق مع مُفتِّش Bun على المنفذ 6499. ويجمع bun run build الخادم والعميل، ويقدّم bun run preview بناء الإنتاج. أما bun run build:static فيُصيّر التطبيق مسبقًا إلى HTML ثابت.

بنية المشروع

يحتوي مشروع Carats نموذجيًا على البنية التالية:

المسارالوصف
src/app.tsنقطة دخول التطبيق الرئيسية. تُركِّب وسيط Carats على Express وتُشغّل خادم HTTP.
src/vite-env.d.tsمرجع أنواع Vite للعميل. يوجد في src/vite-env.d.ts، لا داخل src/client.
src/client/index.htmlقالب HTML الذي يُصيّره الخادم. يجب أن يحتوي على العنصرينمكانين <!--app-head--> و<div id="app"><!--app-html--></div>.
src/client/entrypoint.tsنقطة دخول العميل. تُركِّب الأوجه في المتصفح وتبدأ التصيير في جانب العميل.
src/client/facets.tsxتعريفات المسارات، يشترك فيها العميل ونقطة دخول الخادم.
src/client/base.sassورقة أنماط عامة تحوي رموز التصميم وعمليات التصفير الأساسية.
src/client/pages/مكونات الصفحات. يُصدِّر كل مجلد فرعي مكوّنًا افتراضيًا من index.tsx وقد يستورد ملف SASS خاصًا به.
src/client/components/مكونات مشتركة تستخدمها الصفحات.
src/server/entrypoint.tsنقطة دخول الخادم للتصيير على الخادم. تُصدِّر defineServerEntry(facets) وتُثبّت الدوال الخادمية.
src/server/culets.tsالدوال الخادمية (culets)، وهي دوال بيانات جانب الخادم التي تستخدمها المكونات المُبرَزة.
src/dto/واجهات TypeScript عامة. تُدرَج عبر typeRoots حتى يُحل culet(...) دون استيراد.
public/أصول ثابتة تُقدَّم من جذر الموقع.

الخطوات التالية

اقرأ صفحة المفاهيم الأساسية لتفهم كيف تتضافر JJSX والأوجه والدوال الخادمية وخصائص الخادم معًا، ثم اطلع على صفحتي المكونات والتصيير على الخادم.