سفر در حال توسعه یک پلاگین Obsidian قسمت 2 – بهبود معماری، مدیریت خطاهای اساسی و موارد دیگر!

به قسمت دوم خوش آمدید! در قسمت اول، اصول ایجاد یک پلاگین Obsidian را بررسی کردیم. اگر آن را از دست دادید، توصیه می کنم ابتدا آن را بخوانید. اکنون معماری کلی و طرحبندی فایل افزونه را بهبود میبخشیم و همچنین مدیریت خطاهای اولیه را اضافه میکنیم. علاوه بر این، من آموخته های خود را از انتشار اولین نسخه های پچ به اشتراک می گذارم، اجازه دهید شروع کنیم!
با شروع از پلاگین-الگوی ذکر شده، ساختار کلی افزونه مجموعه ای از فایل ها هستند که همگی در پوشه ریشه مخزن هستند:
main.ts
styles.css
manifest.json
versions.js
در حالی که فایل های تنظیمات فنی مانند نمایش داده نمی شود package.json
. کل کد منبع افزونه ها، از جمله تنظیمات، رابط کاربری و منطق آن در یک فایل واحد موجود است. main.ts
. در حالی که در خدمت نقطه شروع و الگو است، این ساختار خوبی برای توسعه بیشتر ویژگی ها نشان نمی دهد.
قبل از تشریح چیدمان و معماری فعلی، اجازه دهید ابتدا برخی از دستورالعملهای کلی مورد استفاده در این فرآیند را مرور کنیم:
- ساده شروع کنید و پیشرفت کنید / با رشد خود آشتی کنید: اگر پروژه ساده خود را با معماری نهایی و مقیاس پذیر شروع کنید، هیچ چیزی برنده نمی شوید. ساده با نیازهای فعلی خود شروع کنید و در عین حال آماده تغییرات باشید.
- وظایف مختلف را در فایل های مختلف جدا کنید. ما می خواهیم از شر یک مجرد خلاص شویم
main.ts
، که مسئول تمام جنبه های افزونه است. با انجام این کار، ابتدا شروع کردم به جدا کردن تمام کلاسهای داخلmain.ts
به فایل های خودشان و همه آنها را به a منتقل کردندsrc
دایرکتوری بازده:
src
| commands.ts
| gemini-client.ts
| main.ts
| settings-tab.ts
| settings.ts
package.json
package-lock.jsoon
README.md
ایده اصلی پشت این ساختار، جداسازی وظایف مختلف افزونه به فایلهای خودش است: settings-tab.ts
و settings.ts
UI و ساختارهای داده را برای تنظیمات API-Key مورد نیاز تعریف می کند.
تنها دستور این افزونه (با فضایی برای افزودن بیشتر) در تعریف شده است commands.ts
و gemini-client.ts
کتابخانه رسمی Gemini را برای موارد استفاده خاص این افزونه چکیده می کند و توسط دستور استفاده می شود. تمام قطعات به هم متصل شده اند main.ts
که افزونه را در داخل بوت استرپ می کند onload
تابع:
export default class GeminiGenerator extends Plugin {
settings: GeminiGeneratorSettings;
// Loads the plugin.
async onload() {
await this.loadSettings();
this.addSettingTab(new GeminiGeneratorSettingTab(this.app, this));
this.addEditorCommands();
}
private addEditorCommands() {
for (const command of getEditorCommands(this)) {
this.addCommand(command);
}
}
...
}
برخلاف نسخه اولیه، main.ts
از تمام وابستگی های فرمان خلاص شد. فقط تنظیمات را کنترل می کند و همه دستورات ویرایشگر را ثبت می کند (خط 10). این ثبت با ترکیبی از توابع کارخانه و تزریق وابستگی.
خلاصه سریع، دستورات ویرایشگر در ابسیدین با فراخوانی ثبت می شوند addCommand
، ارائه یک شی با پیکربندی دستورات و فراخوانی که اجرای دستورات را نشان می دهد:
this.addCommand(
{ id: 'print-greeting-to-console',
name: 'Print greeting to console',
callback: () => { console.log('Hey, you!');
},
});
از این رو، ما تنها قادر به ثبت یک فرمان در یک زمان هستیم. دلیلش همین است، روش خصوصی addEditorCommands
از main.ts
بر روی لیستی از دستورات، که توسط بازگردانده شده است، تکرار می شود getEditorCommands
و آنها را یک به یک ثبت می کند. از آنجایی که اجرای دستورات نیاز به ارجاع به افزونه به ترتیب ویرایشگر دارد، this
به عنوان استدلال تصویب می شود.
پیاده سازی نسبتاً ساده است: این روش به سادگی فهرستی از تمام دستورات (در حال حاضر یک) را که از طریق متناظر آنها ایجاد شده اند، برمی گرداند. عملکرد کارخانه، که اینترن شی دستور ذکر شده مورد نیاز Obsidian API را می سازد و برمی گرداند.
export const getEditorCommands = (plugin : GeminiGenerator) =>
[
buildGenerateNoteCommand(plugin)
];
با اضافه شدن دستورات بیشتر، ایجاد یک پوشه جدید می تواند مفید باشد Commands
، جایی که هر دستور در فایل خود تعریف می شود.
در مجموع، این ساختار چندین مزیت دارد:
- تفکیک واضح تر نگرانی ها
- مقیاس پذیری بهبود یافته برای ویژگی های آینده
- تعمیر و نگهداری آسان تر # مدیریت خطای اساسی رسیدگی به خطای فعلی حداکثر حداقل است، اما این مجموعه در مورد به اشتراک گذاشتن تمایلات من است، بنابراین ما به اینجا می رویم! مدیریت خطای اصلی را می توان با چهار خط توصیف کرد:
if(!result){
notice.setMessage("❌ An error occured during the Google Gemini Request")
return;
}
اساساً اگر در حین درخواست به Google Gemini خطایی رخ دهد، یک خطای کوچک نشان داده می شود. این برای ابتدا خوب بود، اما برای کاربر خیلی دقیق نیست، زیرا برخی از اعلانها از پیام خطای متفاوتتری بهره میبرند.
از این رو، من به شما پیشنهاد می کنم در مورد موارد خطا و پیام های ممکن فکر کنید. کاربران خود را با پیام های فنی تحت فشار قرار ندهید، در حالی که اطلاعات کافی برای تشخیص خطای ورودی از یک خطای سرور نمایش داده می شود.
من از یک GitHub Action کوچک برای باندل کردن یک GitHub Release هر زمان که یک تگ git فشار داده یا ایجاد می کنم استفاده می کنم. نسخه GitHub به عنوان یک پیش نویس ایجاد می شود، به طوری که من می توانم گزارش یا عنوان انتشار را تطبیق دهم. اگر از این تنظیمات نیز استفاده میکنید، فراموش نکنید که این نسخه را منتشر کنید، زیرا در غیر این صورت هیچکس دیگر نمیتواند افزونه شما را بهروزرسانی یا دانلود کند. این به این دلیل است که در مخزن شما، versions.json
در حال حاضر شامل نسخه جدید شما است، اما از آنجایی که نسخه GitHub هنوز یک پیش نویس است، هیچ کس قادر به دانلود آن نیست.
اگر تنظیماتی مانند من دارید، توصیه می کنم این روش را دنبال کنید:
- یک تگ git را برای نسخه جدید فشار دهید
- منتظر بمانید تا Action تمام شود
- پیشنویس انتشار ایجاد شده را اعتبارسنجی کنید
- انتشار را منتشر کنید
باز هم ممنون که این سریال کوچک را خواندید و دنبال کردید. مثل همیشه، اگر پیشنهاد یا بازخوردی دارید، خوشحال می شوم در نظرات از شما بشنوم! من مشتاقانه منتظر هستم که زمان بیشتری برای توسعه بیشتر افزونه داشته باشم. در قسمت بعدی تنظیمات و دستور دیگری را اضافه می کنیم پس با ما همراه باشید!