تجميع الأصول
دليل لفهم كيفية عمل تجميع الأصول الثابتة في إطار عمل Frappe.
يأتي Frappe مزودًا بواجهة إدارة غنية يمكن الوصول إليها عبر /app، وهي تطبيق صفحة واحدة (SPA) مكتوب ببناء جملة JavaScript حديث، وتنسيقات مكتوبة بملفات SASS (.scss). هذه الملفات غير مفهومة مباشرة من قبل المتصفح، وبالتالي تحتاج إلى تجميع قبل إرسالها إلى المتصلف لتحليلها وتنفيذها.
يأتي Frappe مزودًا بأداة تجميع الأصول (asset bundler) التي يمكنها تجميع أصول جانب العميل مثل:
.js(بناء جملة حديث مع import و export).ts(ملفات TypeScript).vue(مكونات Vue ذات الملف الواحد).css(CSS معالجة باستخدام PostCSS).scss(ملفات SASS).sass(ملفات SASS مع بناء جملة المسافة البادئة).styl(ملفات Stylus).less(ملفات Less)
يتم تجميع هذه الملفات إلى .js أو .css حسب النوع وإرسالها إلى المتصفح.
بناء الأصول
لتجميع الأصول باستخدام أداة تجميع الأصول، قم بتشغيل الأمر التالي من مجلد frappe-bench:
$ bench build
يمكنك أيضًا تشغيله لتطبيقات محددة من خلال إعطائه خيار --apps.
# بناء أصول frappe فقط
$ bench build --apps frappe
# بناء أصول frappe و erpnext فقط
$ bench build --apps frappe,erpnext
وضع المراقبة
عندما تعمل مع الملفات المجمعة، تحتاج إلى تشغيل أمر البناء في كل مرة تقوم فيها بإجراء تغيير على ملفات المصدر الخاصة بك. تأتي أداة تجميع الأصول مع وضع المراقبة حيث تستمع إلى التغييرات في نظام الملفات وتعيد البناء عندما يتغير ملف.
سيؤدي تشغيل الأمر التالي إلى بدء عملية طويلة الأمد تراقب ملفاتك وتعيد بنائها عند تغييرها. ستسجل سطرًا يحتوي على نص "Compiled changes..." في كل مرة تقوم بإعادة بناء.
$ bench watch
Watching for changes...
1:17:28 PM: Compiled changes...
يمكنك أيضًا تشغيله لتطبيقات محددة من خلال إعطائه خيار --apps.
# مراقبة أصول erpnext فقط
$ bench watch --apps erpnext
بدءًا من الإصدار 14، سيتم إعادة تحميل Desk تلقائيًا إذا تم إعادة بناء الأصول في وضع المراقبة. يمكن تبديل هذا السلوك عن طريق تعيين متغير البيئة LIVE_RELOAD، أو تغيير قيمة live_reload في common_site_config.json.
ملفات الحزمة
ملف الحزمة هو نقطة دخول لأصل يتم التقاطه بواسطة الأداة المجمعة للتجميع. على سبيل المثال، إذا كان هناك ملف باسم main.bundle.js في المجلد public لتطبيقك، فسيتم التقاطه تلقائيًا بواسطة الأداة المجمعة وتجميعه في /assets/[app]/dist/js/main.bundle.[hash].js. يتم إلحاق تجزئة فريدة محسوبة من محتويات المخرجات أيضًا باسم الملف، وهو مفيد لتحديث ذاكرة التخزين المؤقت في المتصفحات.
وبالمثل، إذا كان هناك ملف باسم style.bundle.scss في المجلد public، فسيتم تجميعه إلى /assets/[app]/dist/css/style.bundle.css. لاحظ أن الامتداد تغير من .scss إلى .css لأن المتصفحات يمكنها فهم ملفات CSS ولكن ليس ملفات SASS.
يمكن أن توجد ملفات الحزمة في أي مستوى تداخل في مجلد public، لكن سيتم دائمًا تجميعها إما في dist/js أو dist/css اعتمادًا على نوعها. هذا يعني إذا كان هناك ملف في public/main.bundle.js وملف آخر في public/src/main.bundle.js، فإن المخرجات المجمعة للأخير ستتجاوز الأول. ستطبع الأداة المجمعة أيضًا تحذيرًا لمثل هذه التعارضات.
| الإدخال | المخرج |
|---|---|
[app]/public/main.bundle.js |
/assets/dist/[app]/js/main.bundle.[hash].js |
[app]/public/src/main.bundle.js |
/assets/dist/[app]/js/main.bundle.[hash].js |
[app]/public/src/utils/utils.bundle.js |
/assets/dist/[app]/js/utils.bundle.[hash].js |
[app]/public/main.bundle.ts |
/assets/dist/[app]/js/main.bundle.[hash].js |
[app]/public/main.bundle.css |
/assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/styles/main.bundle.css |
/assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.scss |
/assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.sass |
/assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.styl |
/assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.less |
/assets/dist/[app]/css/main.bundle.[hash].css |
استيراد المكتبات من npm
إذا كنت على دراية بتطوير الويب الحديث، فقد تحتاج إلى تثبيت مكتبات من طرف ثالث من npm واستخدامها في مشروعك.
لنفترض أنك تريد استخدام مكتبة dayjs للعمل مع التاريخ والوقت في تطبيقك. يمكنك أولاً تثبيتها باستخدام yarn عن طريق تشغيل الأمر التالي من جذر مجلد تطبيقاتك.
$ cd frappe-bench/apps/myapp
$ yarn add dayjs
الآن، يمكنك استيرادها في ملفات المصدر الخاصة بك كما يلي:
myapp/public/main.bundle.js
import * as dayjs from 'dayjs';
console.log(dayjs())
تضمين الأصول المجمعة في HTML
عند تجميع ملف حزمة، يحتوي ملف المخرج على تجزئة فريدة. لذلك، لا يمكنك كتابة مسار الملف يدويًا لأنه في المرة القادمة التي تقوم فيها بإجراء تغيير على هذا الملف، ستتغير التجزئة. يوفر Frappe بعض الأدوات المساعدة للقيام بذلك.
تضمين الأصول في ملفات HTML مخصصة
ستخرج طرق Jinja include_script و include_style المسار الصحيح للملف بما في ذلك ترميز HTML لملفات .js و .css على التوالي.
index.html
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
{{ include_style('style.bundle.css') }}
</head>
<body>
{{ include_script('main.bundle.js') }}
</body>
</html>
index.html (المصيَّر)
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="/assets/myapp/dist/css/style.bundle.ABCDEFGH.css">
</head>
<body>
<script type="text/javascript" src="/assets/myapp/dist/js/main.bundle.BYJXV4LB.js"></script>
</body>
</html>
تضمين الأصول في app.html
إذا كنت تريد تضمين أصول مجمعة من تطبيقك في /app، يمكنك استخدام app_include_js و app_include_css لتحميلها في app.html.
[app]/hooks.py
app_include_js = ['main.bundle.js']
app_include_css = ['style.bundle.css']
الحصول على مسار الأصل المجمع
إذا كنت لسبب ما تحتاج فقط إلى مسار الأصل المجمع، يمكنك استخدام طريقة Jinja bundled_asset لإنشائه.
Jinja
{{ bundled_asset('main.bundle.js') }}
المصيَّر
/assets/myapp/dist/js/main.bundle.BYJXV4LB.js
واجهة برمجة تطبيقات Python
هذه الواجهات متاحة أيضًا في python. يمكنك استيرادها من jinja_globals.py.
from frappe.utils.jinja_globals import bundled_asset, include_script, include_style
bundled_asset('main.bundle.js')
تضمين الأصول المجمعة بشكل كسول في /app
إذا كنت تريد تحميل الأصول المجمعة بشكل كسول داخل واجهة الإدارة (/app)، يمكنك استخدام طريقة frappe.require.
frappe.require('main.bundle.js').then(() => {
// main.bundle.js تم تحميله الآن
})
هذا النهج مفيد عندما تريد تحميل الكود الخاص بك بناءً على بعض الشروط. لن يتأثر تحميل الصفحة الأولى وهو أفضل للأداء.
وضع الإنتاج
عند نشر تطبيقك في الإنتاج، يمكنك بناء أصولك في وضع الإنتاج. في هذا الوضع، ستقوم أداة التجميع بتصغير المخرجات النهائية لحزمتك مما يؤدي إلى أحجام ملفات أصغر.
لبناء أصولك في وضع الإنتاج، قم بتشغيل الأمر التالي:
$ bench build --production