توسعه برنامه افزودنی Chrome – برنامه حداقلی را با TypeScript، React، Tailwind CSS و Webpack توسعه دهید

مقدمه
در این وبلاگ، نحوه راه اندازی و توسعه یک افزونه کروم را با استفاده از TypeScript، React، Tailwind CSS و Webpack بررسی خواهیم کرد. ما یک پسوند حداقلی به نام “NoteMe” ایجاد خواهیم کرد تا درک خود را آزمایش کنیم. برنامه افزودنی ما شامل ویژگی های زیر خواهد بود:
- به کاربران اجازه دهید چندین یادداشت برای یک وب سایت خاص اضافه کنند
- کاربران را قادر می سازد یادداشت های ذخیره شده را برای یک وب سایت خاص مشاهده کنند
- گزینه ای را برای حذف یادداشت ها برای یک وب سایت خاص ارائه دهید
- یادداشت ها را به صورت محلی در حافظه مرورگر ذخیره کنید
- به صورت اختیاری یادداشتها را با یک پشتیبان برای ذخیرهسازی ابری همگامسازی کنید
تازه کننده
در این وبلاگ با نحوه ساخت افزونه کروم با استفاده از فناوری های مدرن آشنا می شویم. این راهنما فرض میکند که شما قبلاً با ساختن و آپلود افزونه در Chrome در طول توسعه محلی آشنایی دارید. اگر در این زمینه تازه کار هستید یا نیاز به توضیح دقیق در مورد اصول اولیه دارید، توصیه می کنم وبلاگ قبلی من را بررسی کنید: پیوند
اکستنشن نگاه یواشکی
افزونه شامل اجزای زیر خواهد بود:
- دکمه جابجایی: دکمه ای برای باز و بسته کردن نوار کناری.
- نوار کناری: یک پانل همه کاره که در آن کاربران می توانند: یادداشت های جدید بنویسند. مشاهده یادداشت های ذخیره شده حذف یادداشت های ذخیره شده یادداشتها را با باطن همگامسازی کنید (تدارک در کد موجود است، اگرچه در حال حاضر هیچ باطنی متصل نیست).
-
پنجره بازشو: یک پنجره کوچک که به کاربران امکان می دهد دکمه جابجایی (که برای باز کردن/بستن نوار کناری استفاده می شود) را در موقعیت های از پیش تعیین شده روی صفحه تغییر دهند.
توجه داشته باشید: در حالی که هیچ یکپارچه سازی باطن در این پیاده سازی وجود ندارد، کد شامل مقرراتی برای اتصال یک باطن در آینده است.
در زیر اسکرینشاتهایی وجود دارد که نشان میدهد پسوند پس از تکمیل چگونه به نظر میرسد:
پیش نیازها
قبل از ورود به این آموزش، مطمئن شوید که ابزارهای زیر را روی سیستم خود نصب کرده اید:
- Node.js (نسخه 18.16 LTS یا جدیدتر)
- NPM (Node Package Manager، همراه با Node.js)
- TypeScript
- بسته وب
- ویرایشگر کد VS (یا هر ویرایشگر کد دلخواه شما)
پسوند از 40000 فوت
شکل بالا نمای کلی سطح بالایی از عملکرد داخلی این افزونه را ارائه می دهد. در اینجا چند نکته کلیدی وجود دارد که می توانیم از نمودار استخراج کنیم:
- را اسکریپت محتوا به طور مستقیم با
DOM
صفحه وب والد را قادر می سازد تا محتوای صفحه را تغییر دهد. - پنجره بازشو، پس زمینه، و اسکریپت های محتوا از طریق سیستم پیام رسانی زمان اجرا Chrome با یکدیگر ارتباط برقرار کنند.
- برای کارهای مربوط به فضای ذخیرهسازی Chrome یا تماسهای API پشتیبان، محتوا یا اسکریپت های بازشو مسئولیت را به کارگر پس زمینه با استفاده از سیستم پیام رسانی زمان اجرا
- را اسکریپت پس زمینه به عنوان تنها واسطه با پشتیبان برنامه و فضای ذخیره سازی Chrome عمل می کند. همچنین با استفاده از پیامرسانی زمان اجرا، اعلانها را در صورت وجود به اسکریپتهای دیگر ارسال میکند.
- پنجره بازشو و اسکریپت های محتوا تبادل اطلاعات به طور مستقیم از طریق سیستم پیام رسانی زمان اجرا Chrome.
راه اندازی افزونه
در حالی که پروژههای افزونه کروم ساختار پروژه خاصی را الزامی نمیکنند، اما به یک نیاز دارند manifest.json
فایلی که باید در ریشه دایرکتوری ساخت قرار گیرد. با بهره گیری از این انعطاف پذیری، یک ساختار پروژه سفارشی تعریف می کنیم که به سازماندهی موثر اسکریپت های مختلف کمک می کند. این ساختار امکان استفاده مجدد بهتر از کد را در بین اسکریپت ها فراهم می کند و تکرار را به حداقل می رساند و روند توسعه ما را ساده می کند.
مرحله 1: یک ساختار دایرکتوری اولیه برای پروژه ایجاد کنید
برای شروع، یک ساختار دایرکتوری اساسی برای پروژه راه اندازی می کنیم. می توانید از اسکریپت bash زیر برای ایجاد ساختار اصلی به همراه اسکریپت استفاده کنید manifest.json
فایل:
#!/bin/bash
bash_script_absolute_path=$(pwd)
declare public_paths=("public" "public/assets" "public/assets/images")
declare source_paths=("src" "src/lib" "src/scripts" "src/scripts/background" "src/scripts/content" "src/scripts/injected" "src/scripts/popup" "src/styles")
declare public_directory_path="public"
declare manifest_file="manifest.json"
declare project_name="note-me"
create_directory () {
if [ ! -d "$1" ]; then
mkdir ${1}
fi
}
create_file () {
if [ ! -e "$2/$1" ]; then
touch $2/$1
fi
}
create_public_directories () {
for public_path in "${public_paths[@]}";
do
create_directory $public_path
done
}
create_source_directories () {
for source_path in "${source_paths[@]}";
do
create_directory $source_path
done
}
execute () {
echo "creating project struture at "${bash_script_absolute_path}
create_directory $project_name
cd $bash_script_absolute_path"https://dev.to/"$project_name
create_public_directories
create_source_directories
create_file $manifest_file $public_directory_path
echo "done creating project struture at "${bash_script_absolute_path}" with project name "$project_name
}
execute
اطمینان حاصل کنید که ساختار دایرکتوری شما شبیه آنچه در تصویر زیر نشان داده شده است.
مرحله 2: manifest.json
فایل واقع در public
دایرکتوری باید مطابق شکل زیر ساختار داشته باشد:
{
"manifest_version": 3,
"name": "NoteMe",
"version": "1.0",
"description": "A Chrome extension built with React and TypeScript using Webpack.",
"action": {
"default_popup": "popup.html",
"default_icon": "app-icon.png"
},
"background": {
"service_worker": "background.js",
"type": "module"
},
"content_scripts": [
{
"matches": [""],
"js": ["content.js"],
"run_at": "document_end"
}
],
"permissions": [
"storage",
"activeTab",
"scripting",
"webNavigation"
],
"host_permissions": [""],
"web_accessible_resources": [
{
"resources": ["https://dev.to/nadkarnigaurav/styles.css", "sidebar-open.png", "sidebar-close.png"],
"matches": [""]
}
]
}
نکات قابل توجه:
- پسوند فایل ها هستند
.js
زیرا.ts
فایل ها در آن کامپایل خواهند شد.js
فایل هایی که در زمان اجرا در محیط کروم مورد نیاز هستند. - را
matches
استفاده های میدانی
به عنوان مقدار آن، افزونه را قادر می سازد در هر صفحه وب بارگیری شده در Chrome کار کند. - به سه فایل تصویری اشاره شده است:
app-icon.png
،sidebar-open.png
، وsidebar-close.png
. شما می توانید این فایل ها را در مخزن لینک شده در انتهای این وبلاگ بیابید. - را
manifest.json
فایل باید در سطح ریشه قرار گیردdist
دایرکتوری پس از ساخت پروژه برای اطمینان از این امر، باید تنظیمات وب پک را برای جابجایی مناسب در طول فرآیند ساخت، پیکربندی کنیم.
مرحله 3: مقداردهی اولیه npm و نصب Dependencies
- با مقداردهی اولیه npm در پروژه خود با استفاده از دستور زیر شروع کنید:
npm init -y
- لازم را اضافه کنید وابستگی های توسعه به
devDependencies
بخش پروژه شما دستور زیر را اجرا کنید:
npm i --save-dev @types/chrome @types/react @types/react-dom autoprefixer copy-webpack-plugin css-loader mini-css-extract-plugin postcss postcss-loader style-loader tailwindcss ts-loader typescript webpack webpack-cli webpack-dev-server
- را اضافه کنید وابستگی های زمان اجرا مورد نیاز برای اجرای پروژه:
npm i --save react react-dom
مرحله 4: ایجاد فایل های ارجاع شده در manifest.json
فایل های زیر را ایجاد کنید که به آنها ارجاع داده شده است manifest.json
: backgroun.ts
، content.ts
و popup.html
.
-
background.ts
: این فایل را درsrc/scripts/background
دایرکتوری -
content.ts
: این فایل را درsrc/scripts/content
دایرکتوری -
popup.html
این فایل را درpublic
دایرکتوری
مرحله 5: به روز رسانی popup
و background
کد
کد زیر را به popup.html
فایل در public
دایرکتوری:
Popup
توجه:
این فایل به عنوان رابط بازشو عمل می کند که وقتی کاربر روی نام برنامه افزودنی در مرورگر کروم کلیک می کند ظاهر می شود. را styles.css
و popup.js
فایلها در مراحل بعدی تولید میشوند، پس لطفاً دنبال کنید.
کد زیر را به background.ts
فایل در src/scripts/background
دایرکتوری:
import { onAppInstalled, onMessage } from "../../lib/worker";
(() => {
chrome.runtime.onInstalled.addListener(onAppInstalled);
chrome.runtime.onMessage.addListener(onMessage)
})();
توجه:
کد بالا دو شنونده را نصب می کند:
- تابع ثبت شده توسط
chrome.runtime.onInstalled.addListener
هر زمان که برنامه افزودنی در مرورگر نصب شود اجرا می شود. این می تواند برای مقداردهی اولیه فضای ذخیره سازی Chrome یا یک Backend (در صورت وجود) با وضعیت از پیش تعریف شده استفاده شود. - تابع ثبت شده توسط
chrome.runtime.onMessage.addListener
هر زمان که اسکریپت پسزمینه پیامی از محتوا یا اسکریپتهای بازشو دریافت کند، اجرا میشود.
علاوه بر این، import
بیانیه شنوندگان را از src/lib
دایرکتوری منطق اصلی برنامه تعبیه شده است src/lib
، امکان استفاده مجدد در زمینه های مختلف (به عنوان مثال، content
و background
اسکریپت ها).
مرحله 6: مروری بر src/lib
دایرکتوری
را src/lib
دایرکتوری منطق اصلی برنامه افزودنی را در خود جای داده است. در زیر یک نمای کلی از ساختار و اجزای اصلی آن آورده شده است:
-
components
دایرکتوری:
شامل تمام اجزای React مورد استفاده در برنامه افزودنی است. -
lib/components/ContentApp.tsx
:
به عنوان کامپوننت ظرف برای اسکریپت محتوا عمل می کند. -
lib/components/NoteMePosition.tsx
:
شامل جزء مسئول اسکریپت پاپ آپ است. -
helpers.ts
:
شامل توابع کمکی است که در سراسر برنامه افزودنی استفاده می شود. -
storage-model.ts
:
تعاملات با فضای ذخیرهسازی محلی Chrome را مدیریت میکند. برای جزئیات بیشتر در مورد ساختار داده های ذخیره شده به این فایل به همراه مراجعه کنیدtypes.ts
. -
types.ts
:
انواع سفارشی مورد استفاده در پسوند را تعریف می کند. -
worker.ts
:
شامل تماسهای پسزمینه برای شنوندگان رویداد پسزمینه است.
برای پیاده سازی دقیق، لطفاً به کد واقعی موجود در مخزن مراجعه کنید.
مرحله 7: نصب React Components
در این مرحله کامپوننت های React را برای رندر سوار می کنیم. این اجزا در دو اسکریپت مختلف نصب شده اند:src/scripts/content/content.ts
و src/scripts/popup/popup.ts
.
اسکریپت پاپ آپ: یافت شده در src/scripts/popup/popup.ts
.
(() => {
const container = document.createElement("div");
container.id = "note-me-position-component-root";
document.body.appendChild(container);
const root = ReactDOM.createRoot(container);
root.render();
})();
اسکریپت محتوا: یافت شده در src/scripts/content/content.ts
.
export const mountContentRootComponent = () => {
const container = document.createElement("div");
container.id = "note-me-component-root";
const shadowRoot = container.attachShadow({ mode: "open" });
document.body.appendChild(container);
const styleLink = document.createElement("link");
styleLink.setAttribute("rel", "stylesheet");
styleLink.setAttribute("href", chrome.runtime.getURL("https://dev.to/nadkarnigaurav/styles.css"));
shadowRoot.appendChild(styleLink);
const shadowContainer = document.createElement("div");
shadowRoot.appendChild(shadowContainer);
const root = ReactDOM.createRoot(shadowContainer);
root.render( );
};
نکات کلیدی:
- اسکریپت های نصب جداگانه: اسکریپت های بازشو و محتوا در زمینه های مختلف عمل می کنند
-
اسکریپت پاپ آپ: اجرا می شود در زمینه
popup.html
صفحه وب که در آن بارگذاری شده است. - اسکریپت محتوا: در متن صفحه وب اصلی بارگذاری شده در مرورگر اجرا می شود.
-
Shadow DOM برای اسکریپت محتوا:
- سبک های تزریق شده توسط اسکریپت محتوا به طور بالقوه می تواند ظاهر صفحه وب اصلی را تحت تأثیر قرار دهد.
- برای جلوگیری از این، ما استفاده می کنیم سایه DOM برای محصور کردن سبک ها، اطمینان از اینکه آنها در پسوند ایزوله می مانند.
- این برای اسکریپت پاپ آپ ضروری نیست، زیرا در محیط ایزوله خود عمل می کند (
popup.html
).
مرحله 8: تنظیمات برای کامپایل و ساخت
افزودن تنظیمات مورد نیاز برای کامپایل و ساخت پسوند
برای کامپایل و ساخت موفقیت آمیز پسوند، باید فایل های زیر را پیکربندی کنیم:
postcss.config.js
tailwind.config.js
-
tsconfig.json
webpack.config.js
نکات کلیدی:
- تنظیمات پیش فرض: در صورت امکان، تنظیمات پیشفرض برای سادهسازی فرآیند و اطمینان از اینکه تمرکز روی هدف اصلی باقی میماند، یعنی ایجاد یک برنامه افزودنی کاملاً کاربردی، ارائه میشود.
- جزئیات در مخزن: برای تنظیمات کامل و تنظیمات دقیق این فایل ها لطفا به مخزن کد مراجعه کنید.
این پیکربندی ها کامپایل TypeScript، ادغام Tailwind CSS، و فرآیند کلی ساخت Webpack برای برنامه افزودنی را مدیریت می کنند.
تست افزونه
-
ایجاد کنید
dist
دایرکتوری: دستور زیر را برای ایجاد آن اجرا کنیدdist
دایرکتوری:npm run build
-
آپلود در کروم:
- Chrome را باز کنید و به آن بروید
chrome://extensions/
. - فعال کردن حالت توسعه دهنده در گوشه سمت راست بالا
- را کلیک کنید بارگذاری بسته نشده است و انتخاب کنید
dist
دایرکتوری
- Chrome را باز کنید و به آن بروید
-
تأیید نصب:
- پس از بارگیری، نماد برنامه افزودنی به طور پیش فرض در هر صفحه در گوشه سمت راست پایین ظاهر می شود.
-
بررسی عملکرد:
- کنترل موقعیت: از کنترل های موجود در پنجره بازشو برای تغییر موقعیت نماد استفاده کنید.
- ویژگی یادداشت ها: یادداشتها بهطور مستقل برای هر وبسایت ذخیره میشوند و میتوانند برای یک سایت خاص بدون تأثیرگذاری روی دیگران حذف شوند.
-
شبیه سازی Backend:
- در حالی که در حال حاضر هیچ Backendی متصل نیست، کد شامل یک ماده برای ادغام با یکی است.
- پیاده سازی فعلی یک اتصال باطن را با استفاده از تقلید می کند
setTimeout
وpromises
برای شبیه سازی فعل و انفعالات ناهمزمان
در اینجا چند عکس از صفحه نمایش گرفته شده در طول آزمایش برنامه افزودنی وجود دارد.
خوراکی های کلیدی
در اینجا چند نکته کلیدی از این وبلاگ آورده شده است،
- ما بررسی کردیم که چگونه اجزای مختلف محیط Chrome، مانند اسکریپتهای محتوا، اسکریپتهای بازشو، و کارگران پسزمینه، با استفاده از سیستم پیامرسانی زمان اجرا Chrome با یکدیگر ارتباط برقرار میکنند.
- ما یاد گرفتیم که چگونه یک افزونه کروم را از ابتدا پیکربندی و بسازیم، از جمله راهاندازی ساختار پروژه، نصب وابستگیها و نوشتن عملکردهای اصلی.
- ما چند روش خوب را کشف کردیم، مانند:
- افزایش قابلیت استفاده مجدد کد در بین اسکریپت ها برای نگهداری و مقیاس پذیری.
- استفاده از Shadow DOM در اسکریپت های محتوا برای جلوگیری از تضاد سبک با صفحه وب والد.
نگاه اجمالی به جلو
در آینده، من قصد دارم روی وبلاگ دیگری کار کنم که در آن روند انتشار یک برنامه افزودنی کروم کاملاً کاربردی در فروشگاه وب کروم را بررسی کنیم. هدف آن وبلاگ این خواهد بود:
- یک مجتمع توسعه به اندازه کافی برای حل یک مشکل دنیای واقعی ایجاد کنید.
- روند گام به گام انتشار برنامه افزودنی در فروشگاه وب Chrome را نشان دهید.
از اینکه برای خواندن این وبلاگ وقت گذاشتید متشکرم! علاقه و حمایت شما برای من بسیار مهم است. برای به اشتراک گذاشتن بینش های بیشتر در ادامه این سفر هیجان زده هستم.
کد نویسی مبارک!
لینک github: https://github.com/gauravnadkarni/chrome-extension-starter-app
این مقاله ابتدا در Medium منتشر شده است.