تقديم Packem: حزمة تجريبية فائقة السرعة مكتوبة بلغة Rust

Packem عبارة عن مجمّع وحدات JavaScript مُجمَّع مسبقًا تم تطبيقه بشكل أساسي في Rust. يمكنه أيضًا التعامل مع مجموعة متنوعة من أنواع الملفات الأخرى مثل YAML / TOML وملفات تظليل الأجزاء وغير ذلك الكثير. تحقق من موقع الويب أو صفحة GitHub للبدء بسرعة.

يحل Packem تبعيات الوحدة النمطية ويعيد ترطيبها في رسم بياني للوحدة النمطية ، وهي قائمة مسطحة تحتوي على واجهات للوحدة النمطية والتي تعد في الأساس مراجع لهياكل بيانات قابلة للتغيير في الذاكرة تحتوي على بيانات وصفية خاصة لوحدة نمطية في الرسم البياني للوحدة.

يتم تجريد معظم منطق الأعمال في Rust باستخدام روابط FFI لتمكين التفاعلات منخفضة المستوى بين كلا الطرفين. الثنائيات الصدئة متوفرة كملحقات Node C / C ++ مترجمة مسبقًا في الريبو Packem. يتم استخدام CI المستندة إلى مجموعة النظراء لتشغيل عدد قليل من البرامج النصية مع عمليات التثبيت المسبق ، مما ينتج عنه ثنائيات خاصة بنظام التشغيل مع دعم لإصدارات Node اللاحقة (8 ، 9 ، 10).

هذه الطبقة من نواة Packem هي ما يشار إليها بالسياق المنطقي (LC) . يتم إرجاع جميع العمليات الأخرى التي لم يتم تحديد أولوياتها بشكل صريح إلى وقت تشغيل Node العام ، والذي يعتبر وفقًا لشروط Packem سياق وقت التشغيل (RC) . اقرأ المزيد عن السياقات هنا.

نظريًا ، يتم الاحتفاظ بالرسم البياني للوحدة مسطحًا لتجنب المزالق الشائعة التي قد تؤدي إلى عمليات اجتياز غير ضرورية إذا تم استخدام شجرة في مكانها. يسمح ذلك لـ RC بتتبع حالات مثل التبعيات الدائرية العميقة أو عمليات الاستيراد الديناميكية المتداخلة بشدة (تقسيم الكود) ، من بين أمور أخرى ، بشكل مناسب مع الحد الأدنى من آثار الأداء أو الآثار الجانبية قدر الإمكان.

يمكن العثور على مزيد من التفاصيل على موقع Packem's README.md.

كنت أفكر في هذه الفكرة ولكني لم أخطط مطلقًا لتنفيذها حتى انضممت إلى صدام م. لقد كان من مصلحتي حقًا أن أرى تجميع الوحدات كمفهوم آمن لأي شخص للتعلم والفهم والتنفيذ. كان وجود أشخاص يعانون من التكوينات والوثائق والمكونات الإضافية أمرًا مروعًا للغاية وأود أن أغتنم الفرصة لتغيير ذلك. معك. مع Packem.

التاريخ السريع

لقد استغرقت بعض الوقت لاستنفاد معظم الحزم المكتوبة في بيئة غير جافا سكريبت. لقد اكتشفت أن معظمهم نسوا أنه من المفترض أن يكونوا مجمعين وليس مكتبة C / C ++ من أول 19 ثانية.

ما أردته هو أداة تجميع تقوم بمعظم المهام الثقيلة بلغة قريبة من المعدن للمستخدم دون الحاجة إلى أي تفاعل مع عناصرها الداخلية. ثم وجدت Rust. لغة أنظمة ذكية وموجزة تُظهر بعض الميزات الجديرة بالثناء مثل نموذج التزامن الشجاع ، ونوع الأمان ، والمزيد! أتوقع الكثير من استخدام C / C ++ لكنني أفضل التمسك بـ Rust لأنه واضح جدًا عندما يتعلق الأمر بإدارة الذاكرة.

لماذا مجمع آخر؟

إذن ما الأمر هنا؟ لماذا نحتاج إلى أداة إنشاء أخرى نظرًا لأن لدينا بالفعل أدوات رائعة مثل webpack و Parcel و Rollup وما إلى ذلك؟ سآخذك مع بعض الأسباب. ربما يكون لديك اهتماماتك الخاصة في تقليل أوقات التطوير والإنتاج بشكل كبير.

إنه عام 2019 ، لسنا بحاجة إلى أدوات بطيئة بعد الآن

على الرغم من أن Packem أسرع من webpack 4 ، إلا أنها أسرع بمرتين من Parcel (مع تجميع متعدد النواة) . في اختبار معياري ، قمنا بتجميع Lodash v4.17.1 مع كل من Packem و Parcel وكانت هذه النتيجة:

لا تأخذ أي مقاعد في ظاهرها. يمكنك اختباره بنفسك هنا.

السبب في أنني لم أزعج نفسي عناء قياس أداء Parcel مقابل webpack هو أن webpack 4 أسرع بكثير من Parcel. لقد أثبتت هذه الحقيقة باستخدام مقاعد Sean T. Larkin الخاصة ويمكن العثور هنا على موضوع على Twitter.

لأننا نستطيع. يمكن لأي شخص ، أليس كذلك؟

بالطبع ، ما سيكون أكثر منطقية هو أننا نستطيع . كانت لدينا فكرة الحصول على أوقات حزم أسرع مع واجهة Rusty إما باستخدام FFI أو WASM (كان لا يزال غير متأكد بحلول ذلك الوقت). كان FFI أكثر منطقية من حيث السرعة وكان DX مهتمًا ، لذلك ذهبنا مع تطبيق Packem في روابط Rust FFI.

لقد واجهنا بعض المشكلات المتعلقة بسلاسل الرسائل ، لذا لم نستخدم الموارد المتاحة كثيرًا. نتيجة لذلك ، استخدمنا عمليات فرعية متعددة للعقد (مع مزرعة عمال عقدة ) ، وهي نفس التقنية التي يستخدمها Parcel للتجميع متعدد النواة ، ولكن للرسوم البيانية للوحدات الأكبر نظرًا لأنه يضيف وقتًا كبيرًا لبدء التشغيل أعلى وقت تشغيل Node عند استخدامه مع الرسوم البيانية للوحدات الصغيرة .

نمط التكوين

كان هذا جزءًا صعبًا. كان هناك الكثير من الأسئلة التي تحتاج إلى إجابة جيدة للتعويض عن اختيار نمط التكوين الصحيح. ثابت أم ديناميكي؟ JSON / YAML / TOML؟ اعتمد اختيارنا بالكامل على ما إذا كنا بحاجة إلى Packem من أجل:

  1. لديك أسلوب تكوين أكثر إتقانًا ، و
  2. كن حذرًا من تكوينات المستخدم المخصصة الأخرى مثل .babelrc أو package.json .

خلاصة القول ، لقد شرعنا في أسلوب تكوين ثابت لأننا وجدنا أنه بالضبط ما نحتاجه. شيء يمكن أن يخبر Packem بشكل معلن عن كيفية إدارة دورة الحزمة . تم توضيح كل حدود وجود تكوين ثابت.

هناك جانب آخر مثير للاهتمام وهو نوع الملف الذي يجب أن نستخدمه للتكوين. JSON هو الأكثر شيوعًا لدى الغالبية العظمى من مطوري JavaScript أو نمط YAML / TOML / XML الأقل شيوعًا ولكن لديهم مزاياهم الخاصة. لا يزال هناك اقتراح لدعم JSON (رقم 5).

لم يتم قطع JSON بسبب كل علامات اقتباس السلسلة غير الضرورية ، والأقواس المتعرجة والكتلة ، وهو أمر منطقي نظرًا لأنه تنسيق لتبادل البيانات . لا يستحق نهج XML-ish أي احترام فيما يتعلق باستخدامه كتنسيق تكوين لأنه يجعل الأمور أسوأ من JSON فيما يتعلق بالأحرف غير الضرورية. قدمت TOML الكثير من الأسطر الجديدة ، ولم يكن تصحيح الأخطاء للخيارات المتداخلة جذابة للعين لأننا علمنا أن مكونات Packem الإضافية يمكن أن تصبح أكثر أمانًا.

الفائز النهائي كان YAML! كان قادرًا على المرور عبر جميع جوانب كونه تنسيق تكوين مناسب (لـ Packem على الأقل). انها:

  1. يجعل التكوين غير مؤلم.
  2. يستخدم أسلوبًا أنيقًا.
  3. لا يزال مألوفًا لدى عين جافا سكريبت
  4. تم تصميمه خصيصًا لحالة الاستخدام هذه (التكوينات) .

فيما يلي مثال على تكوين Packem نموذجي ( packem.config.yml) . تحقق بنفسك وفكر في كتابة نفس المحتوى بأسلوب JSON / TOML / XML-ish.

لمعلوماتك ، لا يلزم سوى الخيارين الأولين! ؟

تمديد Packem

لم يتم تنفيذ هذه الميزة بعد.

قد نحتاج أحيانًا إلى استخدام ميزة غير موجودة بعد ، أو ربما لم يتم تنفيذها في Packem أو خاصة جدًا بمشروعنا . في هذه الحالة ، سيكون لديك طريقتان لحل احتياجاتك:

  1. قم بإنشاء ملحق Packem لحالة الاستخدام الخاصة بك (وهو الخيار الموصى به).
  2. قم ببناء RC مخصص فوق ثنائيات Packem.

يمنحنا استخدام Rust الفرصة لإصلاح LC إلى تنسيقات ثنائية أخرى ، مثل WebAssembly ، والتي ستمكن Packem من عرض أهداف تجميع متعددة:

  1. ملحق C / C ++ قائم على NAPI مع ثنائيات خاصة بالمنصة مطلوبة بواسطة RC الافتراضي الخاص بـ Packem.
  2. ثنائي قائم على WebAssembly والذي يعمل عبر الأنظمة الأساسية ويتم حقنه في RC.
  3. Packem المستقل الافتراضي الذي يستخدم WebAssembly مع تنفيذ متوافق مع المستعرض لـ RC.
لم يتم وضع الأخيرين على الرادار حتى الآن حيث لا تزال عمليات إعادة البناء الداخلية قيد الفرز.

من المتوقع قريبًا أن يوضح لك الدليل المتقدم كيفية إنشاء أداة بناء مخصصة باستخدام ثنائيات Packem لتناسب احتياجاتك الخاصة في حالة احتياجك إلى استخدام Packem خارج بيئات المستعرض والعقد. تكمل هذه الثنائيات إنشاء الرسم البياني بالكامل ، وتكرار التصفية والجوانب الأخرى المتعلقة بالرسم البياني. هذا يعني أنه يمكنك استخدام جهاز التسلسل المخصص ومراقب الملفات ونظام المكونات الإضافية وما إلى ذلك. يشبه إلى حد كبير كيفية إنشاء العارض المخصص الخاص بك عبر OpenGL.

  1. لا يزال بإمكانك تبني نظام المكونات الإضافية لـ Packem لأنه سيسمح لك بدمج النظام البيئي الخاص بـ Packem من المكونات الإضافية مع المجمع المخصص الخاص بك.
  2. إذا لم تكن متأكدًا مما إذا كنت ستحتاج إلى إنشاء أداة تجميع مخصصة أم لا ، فاعلم أنك لن تحتاج إلى ذلك دائمًا. يرجى محاولة تقديم مشكلة أولا.
  3. إنه ضمان أن هذه الثنائيات ستسرع من سير عملك وفقًا لحالة (حالات) الاستخدام المحددة الخاصة بك.

الوضع الحالي

  • ✂ تقسيم الكود لأوضاع التطوير والإنتاج.
  • ؟ CLI محسّن ("- مطوّل") للحصول على معلومات أفضل حول دورة التجميع.
  • ؟ واجهات الوحدة النمطية للسماح بمعالجة سهلة للرسم البياني للوحدة.
  • الأولوية المناسبة. تتلاءم الوظائف الأصلية تمامًا مع LC. هذا يعني أن هناك فرصًا أكبر للبناء السريع.
  • ؟ تصدير N ativeUtils للاستخدام الخارجي للوظائف الأصلية بما في ذلك g enerateModuleGraph الذي يعيد تشغيل عملية إنشاء الرسم البياني للوحدة النمطية. إنه ثقيل ولكنه لا يزال مفيدًا في الحالات التي تحتاج فيها إلى استنساخ الرسم البياني للوحدة النشطة الحالية. يعني استخدامه مضاعفة وقت الإنشاء ، لذا استخدمه بحذر.

ماذا بعد؟

هذه هي الميزات التي نأمل أن تتوفر قريبًا في الإصدارات القادمة. بجهودك يمكننا إنجاز التجميع بالطريقة الصحيحة . عندما يكون Packem في الإصدار 1.0 ، نتوقع الحصول على دعم كامل لجميع الميزات المدرجة أدناه والميزات الأخرى المذكورة في خريطة طريق Packem.

  • حزمة مستقلة متوافقة مع المستعرض من Packem مع LC في WebAssembly من أجل تكامل أوثق مع النظام الأساسي. قدم Axel Rauschmayer بالفعل طلب ميزة للحصول على إصدار متوافق مع Node في WASM. للتسجيل ، سنعمل على كليهما قريبًا.
  • تهتز الأشجار ، لكنها متقدمة. يجب أن يكون حل عمليات الاستيراد المسماة / غير المسماة وإزالة الشفرة الميتة أمرًا سهلاً. وهذا يعني يمكنك استخدام المكتبات مثل lodash بدلا من lodash-ES دون الحاجة إلى القلق ما إذا كان سيتم التعليمات البرمجية elided أم لا.
  • التكوين التلقائي. مثل Zero Config ، لكن مع التركيز على الإعدادات الافتراضية لمزيد من المرونة.
  • خيارات CLI المتقدمة لجعل التطوير باستخدام Packem طبيعة ثانية.
  • أفضل الإبلاغ عن الخطأ.
  • المزيد من أهداف البيئة. يمكن لـ Packem تجميع حزمة للمتصفح فقط اعتبارًا من الآن. في النهاية ، نتوقع دعم Node CJS والتنسيقات الأخرى أيضًا.
  • المزيد من الإضافات. نحن بحاجة إلى المزيد من المكونات الإضافية! يحتوي Packem على مجموعة من المكونات الإضافية الشائعة لتبدأ بشكل أسرع. ولكن لتنمية مجتمع ، سنحتاج إلى نظام بيئي رائع من المكونات الإضافية. تحقق من المكونات الإضافية الشائعة المتاحة أو قسم المكونات الإضافية على الموقع لبدء تطوير مكون إضافي على الفور.
  • وأكثر بكثير…

مصادر

  • Packem على جيثب
  • طلبات خارطة الطريق والميزات
  • موقع Packem الرسمي
  • إنشاء ملحقات مع Packem
  • تقسيم الكود مع Packem
  • الرسم البياني للوحدة

لم تصل Packem إلى 1.0 حتى الآن . إذا وجدت أن Packem مثيرة للاهتمام بالنسبة لك على الإطلاق ، فحاول المساهمة في Packem نفسها عن طريق إنشاء مكونات إضافية ، وتحديث الوثائق ، ودعمنا ماليًا ، وتمثيل Packem في المؤتمرات أو أي وسيلة أخرى. نحن نقدر جهودك!

تجميع سعيد! ؟؟؟