نحوه ساخت CLI با استفاده از TypeScript و Bun

رابط خط فرمان (CLI) برنامه ای است که در ترمینال اجرا می شود. ورودی های کاربر ، دستورات را پردازش می کند و توابع سیستم را اجرا می کند.
در اوایل محاسبات ، ترمینال تنها راه تعامل با رایانه بود. امروز ، بیشتر کاربران برای استفاده از رایانه خود به رابط های کاربر گرافیکی (GUI) متکی هستند – برخی حتی نمی دانند که زمانی مانند آن وجود داشته است :). با این حال ، به عنوان یک توسعه دهنده نرم افزار ، CLI بخش مهمی از نوار ابزار توسعه شما است. ما به طور مکرر از آن برای نصب کتابخانه ، تنظیمات Docker و چندین اتوماسیون دیگر استفاده می کنیم که غیر عملی با GUI هستند.
این آموزش به شما نشان می دهد که چگونه می توانید CLI را با استفاده از TypeScript و Bun-یک زمان اجرا سریع و همه در یک جاوا اسکریپت-ساخت. اگر فیلم را ترجیح می دهید ، می توانید این ویدیوی YouTube را مشاهده کنید که حاوی همان محتوا است.
https://www.youtube.com/watch؟v=nyvdxzdksuc
آنچه می خواهید بسازید
این آموزش شما را گام به گام در ساخت CLI برای بارگذاری پرونده ها یا دایرکتوری ها در ذخیره سازگار با S3 راهنمایی می کند. با پایان این آموزش ، شما می دانید که چگونه استدلال های خط فرمان را تجزیه کنید و CLI خود را به منتشر کنید NPM رجیستری ما از S3 API در Bun استفاده خواهیم کرد میمون، یک کتابخانه CLI Helper که پرچم ها را تجزیه می کند و به آنها کمک می کند.
در اینجا نگاهی اجمالی به آنچه شما تا پایان این آموزش ایجاد خواهید کرد.
تنظیم و ساختار پروژه
بیایید با ایجاد یک پروژه BON و نصب وابستگی های لازم شروع کنیم. ترمینال خود را باز کنید و دستور زیر را اجرا کنید:
mkdir s3upload && cd s3upload
bun init -y
bun add meow
دستوراتی که شما به تازگی اجرا کرده اید ، یک پروژه BON به نام ایجاد کرده است S3UPLOAD، و بسته Meow را نصب کرد. میمون در تجزیه و تحلیل استدلال ها و پرچم ها و همچنین:
-
پرچم ها را به شتر تبدیل می کند
-
هنگام استفاده از پرچم ها نفی می کند
--no-
پیشوند -
نسخه خروجی چه زمانی
--version
-
توضیحات خروجی و ارسال متن کمک در هنگام
--help
-
عنوان فرآیند را به نام باینری تعریف شده در Pack.json تنظیم می کند
ما یک index.ts پرونده و این جایی است که ما تمام کد برنامه CLI خود را حفظ خواهیم کرد. باز کردن index.ts پرونده های خود را با بیانیه های واردات زیر جایگزین کنید و جایگزین کنید.
#!/usr/bin/env bun
import { S3Client } from "bun";
import { basename } from "node:path";
import { readdir } from "node:fs/promises";
import meow from "meow";
در کد فوق ، ما واردات را وارد کردیم S3Client
برای تعامل با هر ذخیره سازی شیء سازگار با S3. ما همچنین شامل fs
وت path
ماژول های خواندن پرونده ها و دایرکتوری ها بعداً در آموزش. در بالای پرونده ، متوجه بیانیه Shebang خواهید شد (#!/usr/bin/env bun
) که به سیستم عامل می گوید برای اجرای اسکریپت از زمان اجرا Bun استفاده کند.
استدلال های برنامه را تعریف کنید
مرحله بعدی پس از ایجاد پروژه ، تعریف پرچم ها/گزینه های CLI است که برنامه انتظار دارد. ما به روشی نیاز داریم تا به برنامه بگوییم برای بارگذاری یک فایل خاص یا پرونده ها در یک فهرست. ما همچنین می خواهیم به صورت اختیاری کلید دسترسی و راز مورد نیاز برای تأیید اعتبار با سرویس ذخیره شی را مشخص کنیم.
باز index.ts و در کد زیر چسبانده کنید:
const cli = meow(
`
Usage
$ s3upload
Options
--file, -f Single file to upload
--dir Directory to upload recursively
--region AWS region
--endpoint S3 endpoint/url
--access-key-id AWS access key ID
--secret-access-key AWS secret access key
--help Displays this message
--version Displays the version number
Examples
$ s3upload my-bucket --file index.html
$ s3upload react-site --dir build --access-key-id $AWS_ACCESS_KEY_ID --secret-access-key $AWS_SECRET_ACCESS_KEY --endpoint $S3_URL --region $AWS_REGION
` ,
{
importMeta: import.meta, // This is required
flags: {
file: {
type: "string",
shortFlag: "f",
},
dir: {
type: "string",
},
region: {
type: "string",
},
endpoint: {
type: "string",
},
accessKeyId: {
type: "string",
},
secretAccessKey: {
type: "string",
},
},
}
);
const bucket = cli.input.at(0);
if (bucket) upload(bucket, cli.flags);
else {
console.error("Please provide a bucket name as argument");
cli.showHelp(1);
}
در اینجا ما از meow(helpText, options)
عملکردی برای تعریف رفتار برنامه. ما به آن متن راهنما را برای نمایش و تعریف پرچم ها در پارامتر دوم دادیم. در flags
شیء پرچم ها را به عنوان کلیدها به همراه نوع و اختیاری آنها مشخص می کند shortFlag
(یا نام مستعار).
اگر --version
یا --help
پرچم ها بخشی از استدلال های منتقل شده به برنامه نیستند ، پیش می رود تا بقیه کد را اجرا کند. در این حالت ، آن را صدا می کند upload()
عملکرد اگر سطل مشخص شده باشد ، در غیر این صورت ، یک پیام خطا نشان می دهد و متن راهنما را چاپ می کند.
بارگذاری پرونده ها با استفاده از مشتری S3 Bun
در این بخش ، ما قصد داریم upload()
برای بارگذاری پرونده ها یا دایرکتوری ها با کد کار کنید. بیایید ابتدا با کد شروع کنیم تا پرونده ها بارگذاری شود.
عملکرد زیر را در index.ts پرونده:
async function upload(bucket: string, flags: typeof cli.flags) {
if (!flags.file && !flags.dir) {
console.error("Either --file or --dir must be specified");
process.exit(1);
}
const client = new S3Client({
bucket: bucket,
region: flags.region,
accessKeyId: flags.accessKeyId,
secretAccessKey: flags.secretAccessKey,
endpoint: flags.endpoint,
});
if (flags.file) {
const key = basename(flags.file);
await client.write(key, Bun.file(flags.file));
console.log(`✓ Uploaded ${key} to ${bucket}`);
return;
}
}
در upload()
عملکرد ابتدا بررسی می کند که آیا پرچم پرونده یا دایرکتوری مشخص شده است. اگر پرچم فایل تنظیم شده باشد ، از آن استفاده می کند client.write()
روش بارگذاری پرونده. client
نمونه ای از S3Client
در صورت مشخص شدن از AccessKeyID ، منطقه ، نقطه پایانی و SecretAccessKey استفاده می کند. در غیر این صورت ، آن اعتبار را از متغیر محیط می خواند (به مستندات متغیرهای محیط مراجعه کنید).
در مرحله بعد ، ما کد را برای خواندن دایرکتوری و بارگذاری پرونده ها در آن فهرست اضافه خواهیم کرد.
async function upload(bucket: string, flags: typeof cli.flags) {
//...The rest of the code from the previous snippet
if (flags.dir) {
// Handle recursive directory upload
const directoryContent = await readdir(flags.dir, {
recursive: true,
withFileTypes: true,
});
const files = directoryContent.reduce((acc: string[], dirent) => {
if (dirent.isFile()) {
acc.push(
dirent.parentPath
? dirent.parentPath + "/" + dirent.name
: dirent.name
);
}
return acc;
}, []);
for (const file of files) {
await client.write(file, Bun.file(file));
console.log(`✓ Uploaded ${file} to ${bucket}`);
}
console.log(`Uploaded ${files.length} files to ${bucket}`);
}
}
ما استفاده کردیم readdir()
عملکرد برای خواندن بازگشتی محتوای فهرست مشخص شده. ما نتیجه را فیلتر می کنیم تا فقط پرونده ها را بدست آوریم و به طور غیر همزمان آنها را بارگذاری کنیم.
این تنها چیزی است که ما برای تهیه خود نیاز داریم S3UPLOAD CLI کار می کند. اگر ترمینال را باز کرده و دستور را اجرا کنید bun index.ts
باید آن را ببینید که آن پرونده را در سطل مشخص شده بارگذاری کنید.
نحوه بسته بندی و انتشار CLI
تاکنون ما توانسته ایم برنامه را با استفاده از Bun CLI اجرا کنیم ، اما می خواهیم آن را توزیع کنیم تا هر کسی بتواند آن را نصب و استفاده کند. ما می توانیم با استفاده از هر یک از موارد زیر آن را بسته بندی و توزیع کنیم:
-
کد را در یک اجرایی باینری کامپایل کنید. سپس ، آن را از طریق ثبت های بسته مانند Homebrew توزیع کنید ، یا اسکریپت نصب را در اختیار افراد قرار دهید که اجرایی را نصب کرده و آن را به مسیر سیستم اضافه کنید.
-
انتشار به رجیستری NPMبشر سپس آن را با استفاده از هر مدیر بسته JavaScript نصب کنید.
ما قصد داریم برویم NPM مسیر رجیستری برای این آموزش. ما باید به روز کنیم بسته پرونده برای شامل اطلاعات زیر:
-
شرح: این بسته را توصیف می کند و در NPM نمایش داده می شود.
-
نسخه: برای گفتن نسخه بسته منتشر شده. این نیز در صورت فراخوانی CLI با CLI استفاده می شود
--version
پرچم -
مخازن: اینجاست که پرونده اجرایی را که NPM (یا هر مدیر بسته) در سیستم نصب می کند ، مشخص می کنیم مسیربشر به همین دلیل ما مشخص کردیم
!/usr/bin/env bun
در آغاز index.tsبشر
باز بسته و این مقادیر را به آن اضافه کنید:
{
//... The rest of package.json
"version": "1.0.0",
"description": "A CLI to upload files to S3",
"bin": {
"s3upload": "index.ts"
}
}
با اضافه شدن ، انتشار بسته به سادگی در حال اجرا است npm publish
بشر اگر آن را به عنوان یک بسته scoped منتشر می کنید ، باید از آن استفاده کنید npm publish --access public
تا آن را به یک بسته عمومی تبدیل کند. این امر به این دلیل است که بسته های scoped به طور پیش فرض به محدود دسترسی
از شما خواسته می شود اگر به رجیستری NPM تأیید نشده اید ، وارد شوید. از طرف دیگر ، می توانید اجرا کنید
npm login
قبل از انتشار
بسته بندی کردن
این آموزش شما را از طریق ساختن یک برنامه خط فرمان با استفاده از TypeScript و Bun راهنمایی می کند. ما یک ابزار برای بارگذاری پرونده ها یا دایرکتوری ها در ذخیره سازگار با S3 ایجاد کردیم. ما یاد گرفتیم که چگونه استفاده کنیم میمون به عنوان یک کتابخانه یاور و مشتری S3 Bun. علاوه بر این ، شما یاد گرفتید که چگونه برنامه CLI را در رجیستری NPM بسته بندی و منتشر کنید.
می توانید کد نمونه را از GitHub بارگیری کرده و Buntastic را کاوش کنید ، ابزاری که برای استقرار و میزبانی وب سایت های استاتیک با استفاده از S3 به عنوان زمینه ذخیره سازی آن طراحی شده است.