مفاهيم ونصائح وحيل Monorepo حولها
Howtos للمترجمة. جديد على monorepos؟ تحقق من هذه الأسئلة الشائعة. تتم إدارة هذا المثال بواسطة Turborepo و Yarn 4 مع نهج الاسم المستعار للمسار A / TypeScript. ليست الطريقة الوحيدة للقيام بها.
مفيد ل
إذا كنت تستمتع ببعض أعمال OSS الخاصة بي في شركتك ، فأنا أقدر حقًا رعاية أو قهوة أو نجمة مقطوعة. هذا يعطيني المزيد من الوقت لتحسينه إلى المستوى التالي.
| Jetbrains | Embie.be | Vercel |
corepack enable
yarn install .
├── apps
│ ├── nextjs-app (i18n, ssr, api, vitest)
│ └── vite-app
└── packages
├── common-i18n (locales...)
├── core-lib
├── db-main-prisma
├── eslint-config-bases (to shared eslint configs)
└── ui-lib (emotion, storybook)
يجب ألا تعتمد التطبيقات على التطبيقات ، ويمكن أن تعتمد على الحزم
يمكن أن تعتمد التطبيقات على الحزم ، ويمكن أن تعتمد الحزم على بعضها البعض ...
.
├── apps
│ ├── vite-app (Vite app as an example)
│ │ ├── src/
│ │ ├── package.json (define package workspace:package deps)
│ │ └── tsconfig.json (define path to packages)
│ │
│ └── nextjs-app (NextJS app with api-routes)
│ ├── e2e/ (E2E tests with playwright)
│ ├── public/
│ ├── src/
│ │ └── pages/api (api routes)
│ ├── CHANGELOG.md
│ ├── next.config.mjs
│ ├── package.json (define package workspace:package deps)
│ ├── tsconfig.json (define path to packages)
│ └── vitest.config.ts
│
├── packages
│ ├── core-lib (basic ts libs)
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── db-main-prisma (basic db layer with prisma)
│ │ ├── e2e/ (E2E tests)
│ │ ├── prisma/
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── eslint-config-bases
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ └── ui-lib (basic design-system in react)
│ ├── src/
│ ├── CHANGELOG.md
│ ├── package.json
│ └── tsconfig.json
│
├── static (no code: images, json, locales,...)
│ ├── assets
│ └── locales
├── docker (docker...)
│ ├── .dockerignore
│ ├── docker-compose.yml (compose specific for nextjs-app)
│ ├── docker-compose.db.yml (general services like postgresql...)
│ └── Dockerfile (multistage build for nextjs-app)
├── .yarnrc.yml
├── package.json (the workspace config)
└── tsconfig.base.json (base typescript config)
{
"name" : "nextjs-monorepo-example" ,
// Set the directories where your apps, packages will be placed
"workspaces" : [ "apps/*" , "packages/*" ] ,
//...
} سيقوم مدير الحزمة بمسح هذه الدلائل ويبحث عن package.json للأطفال. يتم استخدام محتوىها لتحديد طوبولوجيا مساحة العمل (التطبيقات ، libs ، التبعيات ...).
قم بإنشاء مجلد في ./packages/ دليل باسم الحزمة الخاصة بك.
mkdir packages/magnificent-poney
mkdir packages/magnificent-poney/src
cd packages/magnificent-poneyقم بتهيئة حزمة. json باسم الحزمة الخاصة بك.
بدلاً من كتابة
yarn init، تفضل أخذ ./packages/ui-lib/package.json كمثال يعمل وتعديل قيمه.
{
"name" : "@your-org/magnificent-poney" ,
"version" : "0.0.0" ,
"private" : true ,
"scripts" : {
"clean" : "rimraf ./tsconfig.tsbuildinfo" ,
"lint" : "eslint . --ext .ts,.tsx,.js,.jsx" ,
"typecheck" : "tsc --project ./tsconfig.json --noEmit" ,
"test" : "run-s 'test:*'" ,
"test:unit" : "echo "No tests yet"" ,
"fix:staged-files" : "lint-staged --allow-empty" ,
"fix:all-files" : "eslint . --ext .ts,.tsx,.js,.jsx --fix" ,
} ,
"devDependencies" : {
"@your-org/eslint-config-bases" : "workspace:^" ,
} ,
}أضف أولاً الحزمة إلى App Package.json. الطريقة الموصى بها هي استخدام بروتوكول مساحة العمل المدعومة من الغزل و PNPM.
cd apps/my-app
yarn add @your-org/magnificent-poney@ ' workspace:^ 'يمكن العثور على الإلهام في التطبيقات/NextJS-App/Package.json.
{
"name" : "my-app" ,
"dependencies" : {
"@your-org/magnificient-poney" : "workspace:^" ,
} ,
} ثم أضف مسار TypeScript المسار في التطبيق tsconfig.json. سيتيح لك ذلك استيراده مباشرة (لا يلزم بناء)
يمكن العثور على الإلهام في التطبيقات/NextJS-APP/TSConfig.json.
{
"compilerOptions" : {
"baseUrl" : "./src" ,
"paths" : {
// regular app aliases
"@/components/*" : [ "./components/*" ] ,
// packages aliases, relative to app_directory/baseUrl
"@your-org/magnificent-poney/*" : [
"../../../packages/magnificent-poney/src/*" ,
] ,
"@your-org/magnificent-poney" : [
"../../../packages/magnificent-poney/src/index" ,
] ,
} ,
} ,
}ملاحظة:
- لا تحاول ضبط الأسماء المستعارة في Global tsonfig.base.json للحفاظ على صارمة مع تبعيات الرسم البياني.
- يتيح لك النجم في
@your-org/magnificent-poney/*استيراد المجلدات الفرعية. إذا كنت تستخدم ملف برميل (index.ts) ، فيمكن إزالة الاسم المستعار مع النجمة.
قم بتحرير next.config.mjs وتمكين خيار externaldir التجريبي. ردود الفعل هنا.
const nextConfig = {
experimental : {
externalDir : true ,
} ,
} ;إذا كنت تستخدم إصدار NextJS الأقدم ولم يكن لديك علامة تجريبية ، فيمكنك ببساطة تجاوز تكوين WebPack.
const nextConfig = {
webpack : ( config , { defaultLoaders } ) => {
// Will allow transpilation of shared packages through tsonfig paths
// @link https://github.com/vercel/next.js/pull/13542
const resolvedBaseUrl = path . resolve ( config . context , "../../" ) ;
config . module . rules = [
... config . module . rules ,
{
test : / .(tsx|ts|js|jsx|json)$ / ,
include : [ resolvedBaseUrl ] ,
use : defaultLoaders . babel ,
exclude : ( excludePath ) => {
return / node_modules / . test ( excludePath ) ;
} ,
} ,
] ;
return config ;
} ,
} ;ملاحظة: إذا كانت الحزمة المشتركة الخاصة بك تستخدم Bundler SCSS ... فسيكون تكوين حزمة ويب مخصصة ضروريًا أو استخدام مواد النقل التالي ، انظر الأسئلة الشائعة أدناه.
يتم الآن ربط الحزم بتطبيقك ، فقط استيرادها مثل الحزم العادية: import { poney } from '@your-org/magnificent-poney' .
خياري
إذا كنت بحاجة إلى مشاركة بعض الحزم خارج Monorepo ، فيمكنك نشرها على NPM أو مستودعات خاصة. مثال على أساس microbundle موجود في كل حزمة. يمكن إجراء الإصدار والنشر باستخدام Atlassian/ChangeSet ، وهو بسيط مثل الكتابة:
$ yarn g:changesetاتبع الإرشادات ... وارتكب ملف التغييرات. سيظهر "حزم الإصدار" P/R بعد شيكات CI. عند دمجها ، ستنشر إجراء GitHub الحزم مع إصدار Semver الناتج وإنشاء changelogs لك.
ملاحظة:
- حتى لو لم تكن بحاجة إلى النشر ، يمكن لـ ChangeSet الحفاظ على تغيير تلقائي لتطبيقاتك. لطيف - جيد !
- لتعطيل النشر التلقائي لبعض الحزم ، ما عليك سوى تعيين
"private": "true"في Package.json.- تريد ضبط السلوك ، انظر .Changeset/Config.json.
يمكن تشغيل بعض البرامج النصية الراحة في أي مجلد من هذا الريبو وسوف تستدعي نظرائهم المحددة في الحزم والتطبيقات.
| اسم | وصف |
|---|---|
yarn g:changeset | أضف تغييرات لإعلان إصدار جديد |
yarn g:codegen | تشغيل Codegen في جميع مساحات العمل |
yarn g:typecheck | قم بتشغيل TypeChecks في جميع مساحات العمل |
yarn g:lint | عرض مشكلات Linter في جميع مساحات العمل |
yarn g:lint --fix | محاولة تشغيل Linter Auto-Fix في جميع مساحات العمل |
yarn g:lint-styles | عرض مشكلات CSS stylelint في جميع مساحات العمل |
yarn g:lint-styles --fix | محاولة لتشغيل مشكلات الإصلاح التلقائي في Stylelint في جميع مساحات العمل |
yarn g:test | قم بتشغيل اختبارات الوحدة و E2E في جميع مساحات العمل |
yarn g:test-unit | تشغيل اختبارات الوحدة في جميع مساحات العمل |
yarn g:test-e2e | قم بتشغيل اختبارات E2E في جميع مساحات العمل |
yarn g:build | تشغيل بناء في جميع مساحات العمل |
yarn g:clean | تنظيف البناء في جميع مساحات العمل |
yarn g:check-dist | تأكد من تمرير ملفات Build Dist ES2017 (تشغيل g:build First). |
yarn g:check-size | تأكد من أن ملفات Dist Browser ضمن حد الحجم (Run g:build First). |
yarn clean:global-cache | ذاكرة التخزين المؤقت للأدوات النظيفة (Eslint ، Jest ...) |
yarn deps:check --dep dev | سوف تطبع ما يمكن ترقية الحزم على مستوى العالم (انظر أيضًا .ncurc.yml) |
yarn deps:update --dep dev | قم بتطبيق التحديثات المحتملة (قم yarn install && yarn dedupe بعد) |
yarn install:playwright | تثبيت الكاتب المسرحي لـ E2E |
yarn dedupe | خلل مدمج في ملف قفل ملف القفل |
لماذا استخدام
:لبادئة أسماء البرامج النصية؟ إنه مناسب في Yarn 3+ ، يمكننا استدعاء تلك البرامج النصية من أي مجلد في Monorepo.g:هو اختصارglobal:. انظر القائمة الكاملة في Root Package.json.
الأوامر العالمية yarn deps:check yarn deps:update في الحفاظ على نفس الإصدارات عبر Monorepo بأكمله. وهي تعتمد على تحديثات NPM الممتازة (انظر الخيارات ، أي: yarn check:deps -t minor ).
بعد تشغيل
yarn deps:update، مطلوبyarn install.yarn dedupeالتكرارyarn dedupe --checkالغزل يتم فرض فحص مكرر في المثال الإجراءات github.
انظر مثال في ./apps/nextjs-app/.eslintrc.js و eslint-config-bases.
تحقق من محتوى مجلد .husky لمعرفة ما يتم تمكين السنانير. يتم استخدام Lint Lint Lint لضمان تطبيق Lint و أجمل تلقائيًا على الالتزام و/أو الدفعات.
تعتمد الاختبارات على TS-Jest أو Vitest اعتمادًا على التطبيق. جميع الإعدادات تدعم الاسم المستعار مسار TypeScript. يتم تمكين مكتبة رد الفعل في الاختبار عند تورط رد الفعل.
يعيش التكوين في المجلد الجذر لكل تطبيقات/حزم. كمثال انظر
ستجد بعض تدفقات سير العمل على سبيل المثال لعمل github في .github/سير العمل. بشكل افتراضي ، سيضمنون ذلك
يمكن اختيار كل من هذه الخطوات.
لضمان الأداء اللائق ، توجد هذه الميزات في الإجراءات على سبيل المثال:
التخزين المؤقت للحزم (node_modules ...) - تثبيت حوالي 25s
التخزين المؤقت لـ NextJS Build - بني حوالي 20s
يتم تشغيله عند تغييره باستخدام مسارات الإجراءات ، أي:
paths: - "apps/nextjs-app/**" - "packages/**" - "package.json" - "tsconfig.base.json" - "yarn.lock" - ".yarnrc.yml" - ".github/workflows/**" - ".eslintrc.base.json" - ".eslintignore"
يتطلب المكون الإضافي ESLINT أن يتم تعيين إعداد eslint.workingDirectories :
"eslint.workingDirectories": [
{
"pattern": "./apps/*/"
},
{
"pattern": "./packages/*/"
}
],
مزيد من المعلومات هنا
دعم Vercel Monorepos ، راجع وثيقة Vercel-Monorepo-Deploy.
هناك مثال أساسي لبناء صورة Docker ، اقرأ Docker Doc.
قد تتم إضافة وصفات NetLify ، AWS-Amblify ، K8S-Docker ، بدون خادم في المستقبل. ترحيب العلاقات العامة أيضًا.
يتم تثبيت تبعيات التطبيقات وعمليات الاعتماد على الإصدارات الدقيقة. سوف تستخدم DEPS حزم Semver المتوافقة. لمزيد من المعلومات حول هذا التغيير ، راجع التفكير هنا وملف تكوين Renovabot.json5 الخاص بنا.
للمساعدة في الحفاظ على تحديث DEPS ، راجع yarn deps:check && yarn deps:update البرامج النصية و / أو استخدام RENOVATEBOT.
عند إضافة DEP من خلال الغزل cli (أي: الغزل إضافة شيء) ، من الممكن تعيين سلوك الحفظ تلقائيًا عن طريق تعيين
defaultSemverRangePrefix: ""في yarnrc.yml. ولكن هذا من شأنه أن يجعل الافتراضي للحزم/* كذلك. من الأفضل التعامل معyarn add something --exactعلى أساس لكل حالة.