paint-brush
Vite, Cloudflare, Remix, PNPM এবং Turborepo (কোনও বিল্ড স্টেপ নেই) দিয়ে কিভাবে একটি মনোরেপো তৈরি করবেনদ্বারা@josejaviasilis
1,170 পড়া
1,170 পড়া

Vite, Cloudflare, Remix, PNPM এবং Turborepo (কোনও বিল্ড স্টেপ নেই) দিয়ে কিভাবে একটি মনোরেপো তৈরি করবেন

দ্বারা Jose Javi Asilis19m2024/08/28
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

এটি বিল্ড স্টেপ ছাড়াই রিমিক্সের ভিটে ক্লোডুফ্লেয়ার স্থাপনার জন্য একটি মনোরেপো তৈরি করে। এটি আপনাকে এটিকে একাধিক লক্ষ্যে প্রসারিত করতে দেয়
featured image - Vite, Cloudflare, Remix, PNPM এবং Turborepo (কোনও বিল্ড স্টেপ নেই) দিয়ে কিভাবে একটি মনোরেপো তৈরি করবেন
Jose Javi Asilis HackerNoon profile picture
0-item




ভূমিকা

ন্যূনতম কনফিগারেশন সহ Vite এবং Cloudflare Workers-পৃষ্ঠাগুলির সাথে রিমিক্স ব্যবহার করার জন্য আমার একটি উপায় প্রয়োজন।


আমি অন্যান্য সংগ্রহস্থল দেখেছি, যেমন:


কিন্তু তাদের কিছু সীমাবদ্ধতা ছিল:

  1. আমি এটিকে প্রাক-বিল্ড করতে চাইনি, কারণ আমি আরও কনফিগারেশন ফাইলগুলির সাথে সংগ্রহস্থলগুলিকে বিষাক্ত করতে চাইনি।


  2. ক্লাউডফ্লেয়ার কর্মী/পৃষ্ঠাগুলির একটি ভিন্ন লক্ষ্য রয়েছে। এটিকে tsup দিয়ে টার্গেট করা কঠিন হয়ে পড়ে, কারণ পোস্টগ্রেসের মতো প্যাকেজগুলি রিমিক্সে আমদানি করা হলে নোডের নির্ভরতা ভেঙে ফেলবে।


  3. আমার বিভিন্ন টার্গেট (রিমিক্স-ক্লাউডফ্লেয়ার, নোড/বান) ব্যবহার করার একটি উপায়ও দরকার ছিল


তবুও, আমি তাদের ধন্যবাদ জানাই, কারণ তারা এটিকে সম্ভব করার জন্য পথ প্রশস্ত করেছে!


নীচের অংশে ক্ষতিকর অংশ পড়তে ভুলবেন না!

সামাজিক উপর আমাকে অনুসরণ করুন!

আমি উৎপাদনে সেই 1% ত্রুটিগুলি ধরতে জনসাধারণের মধ্যে একটি স্বয়ংক্রিয় পরীক্ষার প্ল্যাটফর্ম তৈরি করছি।


আমি আমার অগ্রগতি শেয়ার করি:


X/Twitter @javiasilis

লিঙ্কডইন @javiasilis

GitHub সংগ্রহস্থল

আপনি এখানে সম্পূর্ণ বাস্তবায়ন অ্যাক্সেস করতে পারেন।

ধাপে ধাপে

প্রয়োজনীয়তা

  1. নোডজেএস
  2. পিএনপিএম
  3. ডকার (ঐচ্ছিক - স্থানীয় ডাটাবেস উদাহরণের জন্য)


যদিও এটি আপনাকে একটি নতুন মনো-রিপোজিটরির মাধ্যমে নিয়ে যায়, এটি একটি বিদ্যমানকে একটিতে রূপান্তর করার জন্য পুরোপুরি বৈধ।


এটিও ধরে নেবে যে আপনার কিছু মনো রেপো জ্ঞান আছে।


দ্রষ্টব্য:

  • "মূলে" আপনার মনোরপোজিটরির শুরুর পথকে বোঝায়। এই প্রকল্পের জন্য, এটি libs এবং packages ডিরেক্টরির বাইরে থাকবে।

Turborepo ইনস্টল করুন

Turborepo আপনার প্রকল্পের স্ক্রিপ্ট এবং আউটপুট পরিচালনা করতে আপনার প্যাকেজ ম্যানেজারের ওয়ার্কস্পেসের উপরে কাজ করে (এটি এমনকি আপনার আউটপুট ক্যাশেও করতে পারে)। এখন পর্যন্ত, রাশ (যা আমি চেষ্টা করিনি এবং পছন্দ করি না) ছাড়াও এটি একমাত্র মনো-রেপো টুল যা কাজ করতে সক্ষম।


NX এর রিমিক্সের Vite সমর্থন নেই (এই লেখার মতো - 28 আগস্ট, 2024)।


https://turbo.build/

 pnpm dlx create-turbo@latest

1. PNPM ওয়ার্কস্পেস কনফিগার করুন

নির্ভরতা পরিচালনা করতে আমরা PNPM এর কর্মক্ষেত্রের ক্ষমতা ব্যবহার করব।


আপনার মনোরেপো ডিরেক্টরিতে, একটি pnpm-workspace.yaml তৈরি করুন।


এর ভিতরে, যোগ করুন:

 packages: - "apps/*" - "libs/*"


এটি পিএনপিএমকে বলবে যে সমস্ত সংগ্রহস্থলগুলি apps এবং libs ভিতরে থাকবে। মনে রাখবেন libs বা packages ব্যবহার করা (যেমন আপনি অন্য কোথাও দেখেছেন) কোন ব্যাপার না।

2. প্রকল্পের মূলে একটি খালি package.json তৈরি করুন:

 pnpm init
 { "name": "@repo/main", "version": "1.0.0", "scripts": {}, "keywords": [], "author": "", "license": "ISC" }


name:@repo/main এটি আমাদের বলে যে এটি অ্যাপ্লিকেশনটির মূল এন্ট্রি। আপনাকে কোনো নির্দিষ্ট নিয়ম অনুসরণ করতে হবে না বা @ উপসর্গ ব্যবহার করতে হবে না। লোকেরা এটিকে স্থানীয়/দূরবর্তী প্যাকেজ থেকে আলাদা করতে বা এটিকে একটি সংস্থায় গোষ্ঠীভুক্ত করা সহজ করতে ব্যবহার করে।

3. প্রকল্পের রুটে turbo.json ফাইল তৈরি করুন:

 { "$schema": "https://turbo.build/schema.json", "tasks": { "build": {}, "dev": { "cache": false, "persistent": true }, "start": { "dependsOn": ["^build"], "persistent": true }, "preview": { "cache": false, "persistent": true }, "db:migrate": {} } }


turbo.json ফাইল টার্বো রেপোকে বলে কিভাবে আমাদের কমান্ড ব্যাখ্যা করতে হয়। tasks কী-এর ভিতরে থাকা সমস্ত কিছুই all package.json-এ পাওয়া জিনিসগুলির সাথে মিলবে৷


লক্ষ্য করুন যে আমরা চারটি কমান্ড সংজ্ঞায়িত করি। এগুলো প্রতিটি সংগ্রহস্থলের package.json-এর স্ক্রিপ্ট বিভাগের সাথে মিলে যায়। যাইহোক, সমস্ত package.json এই কমান্ডগুলি প্রয়োগ করতে হবে না।


যেমন: dev কমান্ডটি turbo dev দ্বারা ট্রিগার করা হবে, এবং এটি প্যাকেজ.json-এর মধ্যে dev পাওয়া সমস্ত প্যাকেজ চালাবে। আপনি যদি এটি টার্বোতে অন্তর্ভুক্ত না করেন তবে এটি কার্যকর হবে না।

4. প্রকল্পের রুটে একটি apps ফোল্ডার তৈরি করুন

 mkdir apps

5. apps ফোল্ডারে একটি রিমিক্স অ্যাপ তৈরি করুন (বা বিদ্যমান একটি সরান)

 npx create-remix --template edmundhung/remix-worker-template


যখন এটি আপনাকে Install any dependencies with npm বলে তখন না বলুন।


  • এইভাবে দেখতে হবে

6. package.json-এর name পরিবর্তন করে @repo/my-remix-cloudflare-app (বা আপনার নাম)

 { - "name": "my-remix-cloudflare-app", + "name": "@repo/my-remix-cloudflare-app", "version": "1.0.0", "keywords": [], "author": "", "license": "ISC" }

7. apps/<app>/package.json থেকে Root-এর package.json এ নির্ভরশীলতা এবং devDependencies কপি করুন

যেমন:

<root>/package.json

 { "name": "@repo/main", "version": "1.0.0", "scripts": {}, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@markdoc/markdoc": "^0.4.0", "@remix-run/cloudflare": "^2.8.1", "@remix-run/cloudflare-pages": "^2.8.1", "@remix-run/react": "^2.8.1", "isbot": "^3.6.5", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240222.0", "@octokit/types": "^12.6.0", "@playwright/test": "^1.42.1", "@remix-run/dev": "^2.8.1", "@remix-run/eslint-config": "^2.8.1", "@tailwindcss/typography": "^0.5.10", "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "autoprefixer": "^10.4.18", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "husky": "^9.0.11", "lint-staged": "^15.2.2", "msw": "^2.2.3", "postcss": "^8.4.35", "prettier": "^3.2.5", "prettier-plugin-tailwindcss": "^0.5.12", "rimraf": "^5.0.5", "tailwindcss": "^3.4.1", "typescript": "^5.4.2", "vite": "^5.1.5", "vite-tsconfig-paths": "^4.3.1", "wrangler": "^3.32.0" } }


8. রুট লেভেলে ডেভডিপেনডেন্সি হিসেবে টার্বো যুক্ত করুন (এটি রিমিক্সের সমস্ত প্যাকেজ ইনস্টল করবে)।

যাচাই করুন যে টার্বো package.json এর devDependencies-এর ভিতরে আছে। যদি এটি তালিকাভুক্ত না হয় তবে নিম্নলিখিত কমান্ডটি চালান:

 pnpm add turbo -D -w


-w পতাকা পিএনপিএমকে ওয়ার্কস্পেস রুটে ইনস্টল করতে বলে।

9. Root package.json-এ নিম্নলিখিত এন্ট্রি যোগ করুন

  • scripts dev কমান্ড যোগ করুন

  • packageManager বিকল্পে যোগ করুন


 { "name": "@repo/main", "version": "1.0.0", "scripts": { "dev": "turbo dev" }, "keywords": [], "author": "", "license": "ISC", "packageManager": "[email protected]", "dependencies": { // omitted for brevity }, "devDependencies": { // omitted for brevity } }

10. pnpm dev চালানোর মাধ্যমে সবকিছু কাজ করছে তা যাচাই করুন

 pnpm dev

11. প্রকল্পের মূলে একটি Libs ফোল্ডার তৈরি করুন। কনফিগার, ডিবি এবং ইউটিলস যোগ করুন:

 mkdir -p libs/config libs/db libs/utils

12. প্রতিটি প্যাকেজের জন্য একটি src/index.ts যোগ করুন।

 touch libs/config/src/index.ts libs/db/src/index.ts libs/utils/src/index.ts
  • index.ts ফাইলটি সমস্ত প্যাকেজ রপ্তানি করতে ব্যবহার করা হবে।
  • সবকিছু কম্প্যাক্ট করতে আমরা ফোল্ডারটিকে আমাদের এন্ট্রি পয়েন্ট হিসেবে ব্যবহার করব।
  • এটি একটি কনভেনশন, এবং আপনি এটি অনুসরণ না করা বেছে নিতে পারেন।

13. একটি খালি package.json তৈরি করুন এবং libs/config/package.json ফাইলে নিম্নলিখিত যোগ করুন:

 { "name": "@repo/config", "version": "1.0.0", "type": "module", "exports": { ".": { "import": "./src/index.ts", "default": "./src/index.ts" } } }

14. libs/db/package.json এর জন্য একই কাজ করুন:

 { "name": "@repo/db", "version": "1.0.0", "exports": { ".": { "import": "./src/index.ts", "default": "./src/index.ts" } } }

15. এবং libs/utils/package.json :

 { "name": "@repo/utils", "version": "1.0.0", "exports": { ".": { "import": "./src/index.ts", "default": "./src/index.ts" } } }


  • আমরা "রপ্তানি" ক্ষেত্র নির্দিষ্ট করি। এটি অন্যান্য সংগ্রহস্থলকে বলে যে প্যাকেজটি কোথায় থেকে আমদানি করতে হবে।
  • আমরা "নাম" ক্ষেত্রটি নির্দিষ্ট করি। এটি প্যাকেজ ইনস্টল করতে এবং অন্যান্য সংগ্রহস্থলে উল্লেখ করতে ব্যবহৃত হয়।

16. (DB) - গুঁড়ি গুঁড়ি এবং পোস্টগ্রেস যোগ করুন

নোট:

  • আমি ORM তুচ্ছ করতে শুরু করছি। আমি 6টি ভিন্ন বিষয় শিখতে 10 বছরেরও বেশি সময় কাটিয়েছি, এবং এটি এমন জ্ঞান যা আপনি স্থানান্তর করতে পারবেন না।

  • নতুন প্রযুক্তি বের হলে আপনার সমস্যা হয়। প্রিজমা ক্লাউডফ্লেয়ার কর্মীদের বাক্সের বাইরে সমর্থন করে না।

  • LLM-এর মাধ্যমে, জটিল SQL কোয়েরি লেখা আগের চেয়ে সহজ।

  • এসকিউএল শেখা একটি সর্বজনীন ভাষা এবং সম্ভবত পরিবর্তন হবে না।


 pnpm add drizzle-orm drizle-kit --filter=@repo/db


কর্মক্ষেত্র স্তরে Postgres ইনস্টল করুন। পিটফল বিভাগটি দেখুন

 pnma add postgres -w


নোট:

  • --filter=@repo/db পতাকা pnpm-কে db সংগ্রহস্থলে প্যাকেজ যোগ করতে বলে।

17. ওয়ার্কস্পেস রিপোজিটরিতে dotenv যোগ করুন

 pnpm add dotenv -w

নোট

  • -w ফ্ল্যাগ পিএনপিএমকে রুট এর package.json এ ইনস্টল করতে বলে

18. সমস্ত প্রজেক্টে কনফিগ প্রজেক্ট যোগ করুন।

 pnpm add @repo/config -r --filter=!@repo/config

নোট :

  • -r পতাকা pnpm কে সমস্ত সংগ্রহস্থলে প্যাকেজ যোগ করতে বলে।
  • --filter=! ফ্ল্যাগ পিএনপিএমকে কনফিগার রিপোজিটরি বাদ দিতে বলে।
  • নোট করুন ! প্যাকেজের নামের আগে

19. (ঐচ্ছিক) উপরের কমান্ডগুলি কি কাজ করে না? .npmrc ব্যবহার করুন

যদি pnpm রিপোজিটরি থেকে প্যাকেজগুলি টেনে নেয়, আমরা প্রকল্পের মূলে একটি .npmrc ফাইল তৈরি করতে পারি।


.npmrc

 link-workspace-packages= true prefer-workspace-packages=true


  • এটি পিএনপিএমকে প্রথমে ওয়ার্কস্পেস প্যাকেজগুলি ব্যবহার করতে বলবে।
  • Reddit থেকে ZoWnx কে ধন্যবাদ, যিনি আমাকে একটি .nprmc ফাইল তৈরি করতে সাহায্য করেছেন

20. Libs/Config এর ভিতরে Shared tsconfig.json কনফিগার করুন

পিএনপিএম ওয়ার্কস্পেসের শক্তি ব্যবহার করে, আপনি কনফিগার ফাইল তৈরি করতে পারেন যা সমস্ত প্রকল্পে ভাগ করা যায়।


আমরা একটি বেস tsconfig.lib.json তৈরি করব যা আমরা আমাদের লাইব্রেরির জন্য ব্যবহার করব।


libs/config এর ভিতরে একটি tsconfig.lib.json ইনস্ট্যান্টিয়েট করুন:

 touch "libs/config/tsconfig.base.lib.json"


তারপর, নিম্নলিখিত যোগ করুন:

tsconfig.base.lib.json

 { "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "lib": ["ES2022"], "module": "ESNext", "moduleResolution": "Bundler", "resolveJsonModule": true, "target": "ES2022", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "allowImportingTsExtensions": true, "allowJs": true, "noUncheckedIndexedAccess": true, "noEmit": true, "incremental": true, "composite": false, "declaration": true, "declarationMap": true, "inlineSources": false, "isolatedModules": true, "noUnusedLocals": false, "noUnusedParameters": false, "preserveWatchOutput": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "sourceMap": true, } } 


21. db সংগ্রহস্থলে db সংযোগ যোগ করুন।

 // libs/db/drizzle.config.ts (Yes, this one is at root of the db package, outside the src folder) // We don't want to export this file as this is ran at setup. import "dotenv/config"; // make sure to install dotenv package import { defineConfig } from "drizzle-kit"; export default defineConfig({ dialect: "postgresql", out: "./src/generated", schema: "./src/drizzle/schema.ts", dbCredentials: { url: process.env.DATABASE_URL!, }, // Print all statements verbose: true, // Always ask for confirmation strict: true, });


স্কিমা ফাইল:

 // libs/db/src/drizzle/schema.ts export const User = pgTable("User", { userId: char("userId", { length: 26 }).primaryKey().notNull(), subId: char("subId", { length: 36 }).notNull(), // We are not making this unique to support merging accounts in later // iterations email: text("email"), loginProvider: loginProviderEnum("loginProvider").array().notNull(), createdAt: timestamp("createdAt", { precision: 3, mode: "date" }).notNull(), updatedAt: timestamp("updatedAt", { precision: 3, mode: "date" }).notNull(), });


ক্লায়েন্ট ফাইল:

 // libs/db/src/drizzle-client.ts import { drizzle, PostgresJsDatabase } from "drizzle-orm/postgres-js"; import postgres from "postgres"; import * as schema from "./schema"; export type DrizzleClient = PostgresJsDatabase<typeof schema>; let drizzleClient: DrizzleClient | undefined; type GetClientInput = { databaseUrl: string; env: string; mode?: "cloudflare" | "node"; }; declare var window: typeof globalThis; declare var self: typeof globalThis; export function getDrizzleClient(input: GetClientInput) { const { mode, env } = input; if (mode === "cloudflare") { return generateClient(input); } const globalObject = typeof globalThis !== "undefined" ? globalThis : typeof global !== "undefined" ? global : typeof window !== "undefined" ? window : self; if (env === "production") { drizzleClient = generateClient(input); } else if (globalObject) { if (!(globalObject as any).__db__) { (globalObject as any).__db__ = generateClient(input); } drizzleClient = (globalObject as any).__db__; } else { drizzleClient = generateClient(input); } return drizzleClient; } type GenerateClientInput = { databaseUrl: string; env: string; }; function generateClient(input: GenerateClientInput) { const { databaseUrl, env } = input; const isLoggingEnabled = env === "development"; // prepare: false for serverless try { const client = postgres(databaseUrl, { prepare: false }); const db = drizzle(client, { schema, logger: isLoggingEnabled }); return db; } catch (e) { console.log("ERROR", e); return undefined!; } }


মাইগ্রেশন ফাইল:

 // libs/db/src/drizzle/migrate.ts import { config } from "dotenv"; import { migrate } from "drizzle-orm/postgres-js/migrator"; import postgres from "postgres"; import { drizzle } from "drizzle-orm/postgres-js"; import "dotenv/config"; import path from "path"; config({ path: "../../../../apps/my-remix-cloudflare-app/.dev.vars" }); const ssl = process.env.ENVIRONMENT === "development" ? undefined : "require"; const databaseUrl = drizzle( postgres(`${process.env.DATABASE_URL}`, { ssl, max: 1 }) ); // Somehow the current starting path is /libs/db // Remember to have the DB running before running this script const migration = path.resolve("./src/generated"); const main = async () => { try { await migrate(databaseUrl, { migrationsFolder: migration, }); console.log("Migration complete"); } catch (error) { console.log(error); } process.exit(0); }; main();

মাইগ্রেশনের পরে এটি কার্যকর করা উচিত


এবং src/index.ts ফাইলে ক্লায়েন্ট এবং স্কিমা রপ্তানি করুন। অন্যগুলো নির্দিষ্ট সময়ে চালানো হয়।

 // libs/db/src/index.ts export * from "./drizzle/drizzle-client"; export * from "./drizzle/schema "


আপনার package.json এ, drizzle-kit generate যোগ করুন এবং মাইগ্রেশন কমান্ড চালানোর জন্য কোডটি যোগ করুন:

 { "name": "@repo/db", "version": "1.0.0", "main": "./src/index.ts", "module": "./src/index.ts", "types": "./src/index.ts", "scripts": { "db:generate": "drizzle-kit generate", "db:migrate": "dotenv tsx ./drizzle/migrate", }, "exports": { ".": { "import": "./src/index.ts", "default": "./src/index.ts" } }, "dependencies": { "@repo/configs": "workspace:^", "drizzle-kit": "^0.24.1", "drizzle-orm": "^0.33.0", }, "devDependencies": { "@types/node": "^22.5.0" } }

22. libs/db এবং libs/utils এর জন্য Shared tsconfig.json ব্যবহার করুন

libs/db এবং libs/utils এর জন্য একটি tsconfig.json তৈরি করুন

 touch "libs/db/tsconfig.json" "libs/utils/tsconfig.json"


তারপর প্রতিটিতে যোগ করুন:

 { "extends": "@repo/configs/tsconfig.base.lib.json", "include": ["./src"], }
  • দেখুন যে @repo/configs আমাদের tsconfig.base.lib.json উল্লেখ করার জন্য পাথ হিসাবে ব্যবহার করা হয়েছে।
  • এটি আমাদের পথ পরিষ্কার করে।

23. TSX ইনস্টল করুন

TypeScript Execute (TSX) হল ts-নোডের একটি লাইব্রেরি বিকল্প। আমরা এটিকে গুঁড়ি বৃষ্টির স্থানান্তর কার্যকর করতে ব্যবহার করব।

 pnpm add tsx -D --filter=@repo/db

24. libs/db ডিরেক্টরিতে একটি খালি .env যোগ করুন

 touch "libs/db/.env"


নিম্নলিখিত বিষয়বস্তু যোগ করুন:

 DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" NODE_ENV="development" MODE="node" 


এটা এই মত কিছু দেখা উচিত


25. আমাদের রিমিক্স প্রকল্পে libs/db সংগ্রহস্থল যোগ করুন

প্রকল্পের মূল থেকে, চালান:

 pnpm add @repo/db --filter=@repo/my-remix-cloudflare-app


যদি এটি কাজ না করে, তাহলে apps/my-remix-cloudflare-app এর package.json-এ যান এবং ম্যানুয়ালি নির্ভরতা যোগ করুন।

 { "name": "@repo/my-remix-cloudflare-app", "version": "1.0.0", "dependencies": { "@repo/db": "workspace:*" } }

workspace:* সংস্করণ ক্ষেত্রে। এটি পিএনপিএমকে কর্মক্ষেত্রে প্যাকেজের যেকোনো সংস্করণ ব্যবহার করতে বলে।


আপনি যদি pnpm add, আপনি সম্ভবত workspace:^ । যতক্ষণ না আপনি স্থানীয় প্যাকেজ সংস্করণগুলি না বাড়ান ততক্ষণ এটি কোন ব্যাপার না।


আপনি যদি ম্যানুয়ালি এটি যোগ করেন, তাহলে প্রকল্পের রুট থেকে pnpm install চালান।


আমাদের প্রকল্পে @repo/db ব্যবহার করতে সক্ষম হওয়া উচিত।

26. আমাদের ইউটিলগুলিতে কিছু ভাগ করা কোড যোগ করুন:

libs/utils/src/index.ts ফাইলে এই কোড যোগ করুন:

 // libs/utils/src/index.ts export function hellowWorld() { return "Hello World!"; }


27. আমাদের রিমিক্স অ্যাপে Libs/Utils ইনস্টল করুন:

 pnpm add @repo/db --filter=@repo/my-remix-cloudflare-app

28. (ঐচ্ছিক) একটি ডকার কন্টেইনার থেকে একটি পোস্টগ্রেস চালু করুন

আপনার যদি পোস্টগ্রেস ইনস্ট্যান্স চালু না থাকে তবে আমরা ডকার-কম্পোজ ব্যবহার করে একটি চালু করতে পারি। দ্রষ্টব্য, আমি ধরে নিচ্ছি আপনি ডকারকে জানেন।


প্রকল্পের মূলে একটি docker-compose.yml ফাইল তৈরি করুন।

 # Auto-generated docker-compose.yml file. version: '3.8' # Define services. services: postgres: image: postgres:latest restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=postgres ports: - "5432:5432" volumes: - ./postgres-data:/var/lib/postgresql/data pgadmin: # To connect PG Admin, navigate to http://localhost:8500 use: # host.docker.internal # postgres # (username) postgres # (password) postgres image: dpage/pgadmin4 ports: - "8500:80" environment: PGADMIN_DEFAULT_EMAIL: [email protected] PGADMIN_DEFAULT_PASSWORD: admin


তারপর আপনি চালাতে পারেন:

 docker-compose up -d

-d পতাকা ডকার-কম্পোজকে বিচ্ছিন্নভাবে চালাতে বলে যাতে আপনি আবার আপনার টার্মিনালে অ্যাক্সেস পেতে পারেন।

29. ডিবি স্কিমা তৈরি করুন

এখন, libs/db সংগ্রহস্থলে নেভিগেট করুন এবং db:generate চালান।

 cd `./libs/db` && pnpm db:generate
  • মনে রাখবেন যে db:generate হল একটি উপনাম: drizzle-kit generate
  • আপনার সঠিক .env আছে তা যাচাই করুন।
  • উপরন্তু, এটি অনুমান করে যে আপনার একটি Postgres দৃষ্টান্ত চলছে।

30. মাইগ্রেশন চালান।

আমাদের ডাটাবেসের মধ্যে সমস্ত সারণী স্ক্যাফোল্ড করার জন্য আমাদের মাইগ্রেশন চালাতে হবে।


libs/db সংগ্রহস্থলে নেভিগেট করুন (যদি আপনি সেখানে না থাকেন) এবং db:generate চালান।

 cd `./libs/db` && pnpm db:migrate
  • মনে রাখবেন যে db:migrate হল এর একটি উপনাম: dotenv tsx ./drizzle/migrate
  • আপনার সঠিক .env আছে তা যাচাই করুন।
  • উপরন্তু, এটি অনুমান করে যে আপনার একটি Postgres দৃষ্টান্ত চলছে।

31. আপনার রিমিক্স অ্যাপের ভিতরে একটি DB কল সন্নিবেশ করুন।

 // apps/my-remix-cloudflare-app/app/routes/_index.tsx import type { LoaderFunctionArgs } from '@remix-run/cloudflare'; import { json, useLoaderData } from '@remix-run/react'; import { getDrizzleClient } from '@repo/db'; import { Markdown } from '~/components'; import { getFileContentWithCache } from '~/services/github.server'; import { parse } from '~/services/markdoc.server'; export async function loader({ context }: LoaderFunctionArgs) { const client = await getDrizzleClient({ databaseUrl: context.env.DATABASE_URL, env: 'development', mode: 'cloudflare', }); if (client) { const res = await client.query.User.findFirst(); console.log('res', res); } const content = await getFileContentWithCache(context, 'README.md'); return json( { content: parse(content), // user: firstUser, }, { headers: { 'Cache-Control': 'public, max-age=3600', }, }, ); } export default function Index() { const { content } = useLoaderData<typeof loader>(); return <Markdown content={content} />; }


  • মনে রাখবেন যে আমরা এখানে সেরা অনুশীলনগুলি অনুসরণ করছি না।
  • আমি আপনাকে আপনার লোডারের মধ্যে সরাসরি কোনও ডিবি কল না করার পরামর্শ দেব, তবে একটি বিমূর্ততা তৈরি করুন যা তাদের কল করে।
  • পরিবেশের ভেরিয়েবল সেট করার ক্ষেত্রে ক্লাউডফ্লেয়ার চ্যালেঞ্জিং। তারা অনুরোধ দ্বারা পাস করছি

32. আপনার .dev.vars এ নিম্নলিখিতটি যোগ করুন:

apps/my-remix-cloudflare-app/.dev.vars

 DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"

33. রিমিক্স প্রকল্প চালান!

পোস্টগ্রেস ইনস্ট্যান্স চালু করুন (যদি প্রস্তুত না হয়)

 docker-compose up -d


প্রকল্প চালু করুন

 pnpm turbo dev 


উন্নত ব্যবহারের ক্ষেত্রে - ক্লাউডফ্লেয়ার কর্মীদের GetLoadContext-এ CQRS।

আমার প্রকল্পগুলিতে, আমি একটি CQRS প্যাটার্ন বাস্তবায়ন করার প্রবণতা , 2 । এটি এই টিউটোরিয়ালের সুযোগের বাইরে।


তবুও, লোড প্রসঙ্গে, আমি একটি মধ্যস্থতাকারী (এবং একটি কুকি ফ্ল্যাশ বার্তা) ইনজেক্ট করার প্রবণতা রাখি যা আমার ব্যবসায়িক যুক্তি থেকে আমার সম্পূর্ণ রিমিক্স অ্যাপ্লিকেশনটিকে ডিকপল করবে৷


এটি এই মত কিছু দেখায়:

 export const getLoadContext: GetLoadContext = async ({ context, request }) => { const isEnvEmpty = Object.keys(context.cloudflare.env).length === 0; const env = isEnvEmpty ? process.env : context.cloudflare.env; const sessionFlashSecret = env.SESSION_FLASH_SECRET; const flashStorage = createCookieSessionStorage({ cookie: { name: "__flash", httpOnly: true, maxAge: 60, path: "/", sameSite: "lax", secrets: [sessionFlashSecret], secure: true, }, }); return { ...context, cloudflare: { ...context.cloudflare, env, }, dispatch: (await dispatchWithContext({ env: env as unknown as Record<string, string>, request, })) as Dispatch, flashStorage, }; };

নোট করুন যে প্রেরণ কোডটি বাদ দেওয়া হয়েছে। এখানে আপনার টাইপস্ক্রিপ্ট ডেভের অভিজ্ঞতা কীভাবে 10x করা যায় সে সম্পর্কে আপনি আমার নিবন্ধে আরও জানতে পারেন।


আমি আমার কোড পরিবর্তন না করেই রিমিক্স বের করতে পারি বা অন্য ভোক্তা ব্যবহার করতে পারি।


কিন্তু….


আপনি যখন টার্বোরেপো ব্যবহার করে মনোরেপো কাঠামোতে কাজ করেন তখন একটি অতিরিক্ত চ্যালেঞ্জ থাকে।


আপনি যদি লোড-প্রসঙ্গের মধ্যে একটি প্যাকেজ থেকে একটি TypeScript ফাইল আমদানি করেন, তাহলে ধরা যাক @repo/db Vite একটি ত্রুটি ফিরিয়ে দেবে যে এক্সটেনশন .ts সহ ফাইলটি অজানা, এবং কীভাবে এটি প্রক্রিয়া করতে হয় তা জানবে না।


এটি ঘটে কারণ লোড-প্রসঙ্গ + ওয়ার্কস্পেসগুলি সাইটের প্রধান আমদানি গ্রাফের বাইরে থাকে, টাইপস্ক্রিপ্ট ফাইলগুলিকে খেলার বাইরে রেখে যায়।


কৌশলটি হল tsx ব্যবহার করা এবং Vite কল করার আগে এটি লোড করা, যা কাজ করবে। এটি গুরুত্বপূর্ণ কারণ এটি নিম্নলিখিত সীমাবদ্ধতাগুলি অতিক্রম করে:


ক্লাউডফ্লেয়ার প্যাকেজ নির্ভরতা।


ক্লাউডফ্লেয়ার প্যাকেজ নির্ভরতা এবং প্রি-বিল্ডিং

প্রথমত, এটি সেই পদক্ষেপ যা আমি এড়াতে চেষ্টা করছিলাম, কারণ এর অর্থ হল যে প্রতিটি প্যাকেজের জন্য আমাকে একটি বিল্ড ধাপ প্রবর্তন করতে হবে, যার অর্থ আরও কনফিগারেশন।


ভাগ্যক্রমে, এটি ক্লাউডফ্লেয়ার পৃষ্ঠাগুলির জন্য কাজ করেনি। নির্দিষ্ট লাইব্রেরি, যেমন Postgres, রানটাইম সনাক্ত করবে এবং প্রয়োজনীয় প্যাকেজ টানবে।


একটি সমাধান আছে: আমরা tsx ব্যবহার করে সমস্ত TypeScript ফাইল লোড করতে পারি এবং চালানোর আগে সেগুলি ট্রান্সপিল করতে পারি।


আপনি যুক্তি দিতে পারেন এটি একটি প্রাক-বিল্ড পদক্ষেপ, কিন্তু যেহেতু এটি এখনও রিমিক্সের সংগ্রহস্থল স্তরে রয়েছে, আমি এই পদ্ধতির সাথে উল্লেখযোগ্য সমস্যাগুলি দেখতে পাচ্ছি না।


এটি সমাধান করতে, আমরা নির্ভরতা হিসাবে tsx যোগ করি:

 pnpm add tsx -D --filter=@repo/my-remix-cloudflare-app


এবং তারপর, আমাদেরকে আমাদের package.json পরিবর্তন করতে হবে এবং আমাদের প্রতিটি রিমিক্স স্ক্রিপ্টে tsx প্রক্রিয়া যোগ করতে হবে:

 { "name": "@repo/my-remix-cloudflare-app", "version": "1.0.0", "scripts": { // Other scripts omitted "build": "NODE_OPTIONS=\"--import tsx/esm\" remix vite:build", "dev": "NODE_OPTIONS=\"--import tsx/esm\" remix vite:dev", "start": "NODE_OPTIONS=\"--import tsx/esm\" wrangler pages dev ./build/client" } }

অতিরিক্ত

একটি .npmrc ফাইল তৈরি করা হচ্ছে

কমান্ড লাইনের সাথে আপনার স্থানীয় প্যাকেজ যোগ করার সময় আপনার সমস্যা হলে, আপনি প্রকল্পের রুটে একটি .npmrc ফাইল তৈরি করতে পারেন।

.npmrc

 link-workspace-packages= true prefer-workspace-packages=true

এটি পিএনপিএমকে প্রথমে ওয়ার্কস্পেস প্যাকেজগুলি ব্যবহার করতে বলবে।


Reddit থেকে ZoWnx কে ধন্যবাদ যিনি আমাকে একটি .nprmc ফাইল তৈরি করতে সাহায্য করেছেন

ক্ষতি -

  1. আপনার ফাইলগুলিতে .client এবং .server নামকরণের সাথে সতর্ক থাকুন। এমনকি যদি এটি একটি পৃথক লাইব্রেরিতে থাকে। এটি একটি ক্লায়েন্ট বা সার্ভার ফাইল কিনা তা নির্ধারণ করতে রিমিক্স এগুলি ব্যবহার করে। প্রকল্পটি সংগ্রহস্থল প্রতি কম্পাইল করা হয় না তাই এটি একটি আমদানি ত্রুটি নিক্ষেপ করবে!


  2. আপনার যদি পোস্টগ্রেসের মতো মাল্টি-প্ল্যাটফর্ম প্যাকেজগুলির সাথে সমস্যা হয় তবে এটি ওয়ার্কস্পেস স্তরে ইনস্টল করা ভাল। এটি সঠিক আমদানি সনাক্ত করবে। এটিকে সরাসরি @repo/db সংগ্রহস্থলে ইনস্টল করা রিমিক্সে আমদানি করার সময় ভেঙে যাবে।


এটা, লোকেরা!!!

GitHub সংগ্রহস্থল

আপনি এখানে সম্পূর্ণ বাস্তবায়ন অ্যাক্সেস করতে পারেন।

সামাজিক উপর আমাকে অনুসরণ করুন!

আমি উৎপাদনে সেই 1% ত্রুটিগুলি ধরার জন্য জনসাধারণের মধ্যে একটি স্বয়ংক্রিয় পরীক্ষা প্রকৌশলী তৈরি করছি।


আমি আমার অগ্রগতি শেয়ার করি:


X/Twitter @javiasilis

লিঙ্কডইন @javiasilis