في الدفاع عن نمطية JavaScript المفرطة: دروس من أزمة left-pad

دقائق القراءة: 3

في الأسبوع الماضي، استحوذت قضية `npmgate` على اهتمام واسع في مجتمع JavaScript. لمن لم يتابع تفاصيل ما حدث، إليكم ملخص سريع: طلبت شركة تُدعى Kik من المطور Azer Koçulu التنازل عن اسم مشروع `kik` على `npm`. رفض Azer ذلك لأنه كان يستخدمه بالفعل. كررت Kik طلبها، وهذه المرة هددت باللجوء إلى المحامين بتهمة انتهاك العلامة التجارية. رفض Azer بشدة، فصعدت Kik الأمر إلى `npm`. انحازت `npm` إلى Kik ونقلت ملكية الوحدة من Azer. رداً على ذلك، كتب Azer مقالاً بعنوان ‘لقد حررت وحداتي للتو’ (I’ve Just Liberated My Modules) وأزال جميع حزماته من `npm`. كانت إحدى الحزم التي أزالها هي `left-pad`. أدى إزالة `left-pad` من `npm` إلى تعطيل عملية التثبيت لأي مشروع يعتمد عليها كإحدى تبعياته. كان تأثير هذا الإجراء هائلاً، حيث كانت هذه الوحدة تُستخدم من قبل عدد كبير من المشاريع الشائعة جداً (مثل Babel و Atom و React على سبيل المثال لا الحصر). اشتعلت شبكة الإنترنت بالجدل!

تسببت هذه الحادثة في طرح عدد من التساؤلات، يمكن تصنيف معظمها ضمن المحاور التالية:

تساؤلات جوهرية أثيرت بعد الأزمة

هل كان هناك انتهاك للعلامة التجارية؟

هذه مسألة قانونية.

هل كان على npm الانحياز لـ Kik؟

هذه مسألة تجارية.

هل يجب أن يكون بالإمكان إلغاء نشر وحدة تعتمد عليها وحدات أخرى؟

هذا قلق تقني.

هل يجب أن تكون وحدات npm قابلة للتغيير؟

هذا قلق تقني.

هل كان ينبغي للمجتمع استخدام وحدات مثل left-pad كتبعيات من الأساس؟

هذه مناقشة أوسع بكثير.

`npm`، وفريقها القانوني، هما من سيتعين عليهما في النهاية حل المشكلات التجارية والقانونية (النقطتان 1 و 2 أعلاه). وسيكون عليهم تحديد ما إذا كان هذا انتهاكاً حقيقياً للعلامة التجارية، وما هي السياسة المتبعة بشأن طلبات مماثلة في المستقبل. أما بالنسبة للنقطة 3 أعلاه (القدرة على إلغاء نشر وحدة تعتمد عليها وحدة منشورة أخرى)، فقد أصدرت `npm` البيان التالي:

npm needs safeguards to keep anyone from causing so much disruption. If these had been in place yesterday, this post-mortem wouldn’t be necessary.

— @izs من kik, left-pad, و npm

على الرغم من أن `npm-shrinkwrap` يمكن أن يساعد في بعض مشكلات قابلية التغيير (النقطة 4)، فإن التخفيف الحقيقي الوحيد الذي رأيته هو تجميع تبعياتك مع الحزمة المنشورة الخاصة بك. يشرح Rich Harris هذا في مقاله ‘كيف لا تفسد الإنترنت بهذه الحيلة الغريبة الواحدة’ (How to not break the internet with this one weird trick).

وهذا يقودنا إلى النقطة 6، والسبب وراء وجود هذا المقال: هل كان ينبغي للمجتمع استخدام وحدات مثل `left-pad` كتبعيات من الأساس؟

فهم وحدة left-pad: جوهر الجدل

لفهم سبب هذا الجدل أصلاً، يجب أن نفهم أولاً ما هي `left-pad`. بالنظر إلى سلسلة نصية (`str`)، وطول (`len`)، وحرف (`ch`)، ستقوم `left-pad` بحشو الجانب الأيسر من `str` بالحرف `ch` حتى يصبح طول السلسلة مساوياً لـ `len`.

إليكم كامل الكود الذي يشغل `left-pad`:

module.exports = leftpad;

function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  len = len - str.length;
  if (len <= 0) return str;
  if (ch === null || ch === undefined || ch === '') ch = ' ';
  ch = String(ch);
  while (++i < len) str = ch + str;
  return str;
}

فكرة أن 17 سطراً من الكود (221 حرفاً) كانت وراء انهيار الإنترنت أثارت الكثير من الشكاوى حول استخدام الحزم شديدة النمطية (hyper-modular) داخل مجتمع JavaScript. ومع ذلك، (أخيراً) أبدأ دفاعي.

دفاع عن نمطية JavaScript المفرطة

حجم وحدة left-pad لا علاقة له بالأزمة

حجم `left-pad` هو مجرد تمويه. عدد الأسطر التي يحتويها لا علاقة له على الإطلاق بالنقاش حول كيفية تسبب إزالتها من بيئة `npm` في تعطيل حزم أخرى. كان من الممكن أن تتسبب إزالة أي حزمة من البيئة في هذا الأمر. أزال Azer 272 وحدة خلال خروجه من `npm`. من الآمن تماماً القول أن `left-pad` كتبها مطور أثبت نفسه في المجتمع. أولئك الذين يجادلون بأن وجود تبعية مثل `left-pad` يضيف خطراً إلى مشروعهم يجادلون في الأساس ضد وجود أي تبعيات `npm` خارجية في مشروعهم.

يمكننا كتابة left-pad بأنفسنا، ولكن لماذا؟

نعم، يمكننا جميعاً كتابة وحدات مثل `left-pad` من الصفر، ولكن لماذا قد نرغب في ذلك؟ السبب الكامل وراء إنشاء مكتبات الأدوات المساعدة مثل jQuery و lodash هو تحسين تجربة المطور. بالتأكيد، الكود وراء `left-pad` ليس معقداً للغاية، وربما يمكن لأي منا إعادة كتابته في بضع دقائق. قد يستمتع البعض حتى بهذا التحويل. ومع ذلك، فإن التبديل السياقي من كتابة الكود الذي يحل المشكلة المطروحة إلى كتابة دالة تعالج السلاسل النصية يبدو استخداماً سيئاً للوقت والطاقة. تذكر، مجرد قدرتنا على فعل شيء لا يعني أننا يجب أن نفعله. في كل يوم، يجب أن نمكّن أنفسنا من التركيز على مشاكل أكبر وأفضل مما كانت عليه في اليوم السابق.

قوة المجتمع والنمو

هناك سبب وراء تفوق `npm` على جميع مديري الحزم الآخرين عندما يتعلق الأمر بالنمو. حاجز الدخول للمشاركة عن طريق نشر حزمة على `npm` صغير للغاية. تمكين المزيد من المطورين من المشاركة في العملية، بغض النظر عن حجم المساهمة، لا يمكن إلا أن يجعل المجتمع أقوى.

المصدر: modulecounts.com

معايير JavaScript للسوق الحرة

لن تتمكن معايير JavaScript على الأرجح أبداً من مواكبة الزخم والسرعة التي يتحرك بها مجتمع JavaScript. وهذا أمر جيد. في هذا العالم الجديد من JavaScript للسوق الحرة، فلتفز أفضل وحدة. يجب أن تنمو الوحدات الجيدة مع زيادة عدد تنزيلاتها ومشاركات المجتمع، بينما ستختفي الوحدات غير المستخدمة أو غير المدعومة ببطء في الهاوية الافتراضية. في الواقع، هناك حالات، مثل `bluebird`، حيث تتفوق مكتبة المجتمع على المكتبة القياسية (انظر 'لماذا وعود ES6 الأصلية أبطأ وأكثر استهلاكاً للذاكرة من bluebird؟' - Why are native ES6 promises slower and more memory-intensive than bluebird؟).

كيف تختار الوحدات الآمنة؟

مع كل هذه الوحدات، كيف تعرف أي منها آمن للاستخدام؟ الحقيقة هي، كما هو الحال مع أي برنامج مفتوح المصدر، أنك لا تعرف على وجه اليقين أبداً. ولكن إليك الاختبار الذي أستخدمه عند تضمين أي شيء من `npm` في مشروعي:

  • هل الحزمة موثقة جيداً؟
  • هل تحتوي على اختبارات؟
  • هل يستخدمها الناس؟
  • هل للمجتمع آراء حولها (عادةً ما ينطبق هذا فقط على الوحدات الأكبر)؟

الأمر لا يتعلق بالحجم، بل بالوظيفة

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

الوحدات تدور حول قابلية التركيب (Composability)

"فكر في وحدات Node.js كقطع ليغو. أنت لا تهتم بالضرورة بتفاصيل كيفية صنعها. كل ما تحتاج لمعرفته هو كيفية استخدام قطع الليغو لبناء قلعة الليغو الخاصة بك."

— Sindre Sorhus من AMA #10

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

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

💡 الخلاصة التقنية

تُظهر أزمة left-pad أهمية التفكير النقدي في تبعيات المشاريع، لكنها في الوقت ذاته تؤكد على القيمة الجوهرية لنمطية JavaScript المفرطة. فالفلسفة التي تدعو إلى بناء أنظمة معقدة من وحدات صغيرة، موثقة جيداً ومختبرة، تعزز قابلية التركيب، وتسرّع وتيرة التطوير، وتتيح للمطورين التركيز على حل المشكلات الكبرى بدلاً من إعادة اختراع العجلة. إن اختيار الوحدات بحكمة، بناءً على جودتها ووظيفتها ودعم المجتمع لها، هو المفتاح للاستفادة القصوى من هذا النهج القوي.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *