مرحبا ، اسمي ديمتري كارلوفسكي ، وأنا ... أعشق مام. يحكم M AM معامل Gnostic M ، مما يوفر لي حصة الأسد من الروتين.

الوحدة النمطية اللاأخلاقية ، على عكس الوحدة التقليدية ، ليست ملفًا مصدرًا ، بل هي دليل يمكن أن توجد فيه رموز مصدر view.tree
لغات: منطق البرنامج على JS
/ TS
، واختباراته على TS
/ JS
، وتكوين المكونات على view.tree
، والأنماط في CSS
، التعريب في locale=*.json
، الصور ، إلخ ، إلخ. إذا رغبت في ذلك ، فليس من الصعب ربط دعم أي لغة أخرى. على سبيل المثال ، ستايلس لكتابة الأنماط ، أو HTML لوصف القوالب.
يتم تتبع التبعيات بين الوحدات تلقائيًا عن طريق تحليل المصدر. في حالة تشغيل الوحدة النمطية ، يتم تشغيلها ككل - يتم تبديل كل شفرة مصدر للوحدة النمطية وتندرج في الحزمة المقابلة: البرامج النصية - بشكل منفصل ، الأنماط - بشكل منفصل ، الاختبارات - بشكل منفصل. بالنسبة إلى الأنظمة الأساسية المختلفة - حزمها: للعقدة - الخاصة بهم ، للمتصفح - الخاصة بهم.
الأتمتة الكاملة ، الافتقار إلى التهيئة والمراجل ، الحد الأدنى من أحجام الحزمة ، الضخ التلقائي للتبعيات ، تطوير مئات المكتبات والتطبيقات المنفردة في قاعدة كود واحدة دون ألم ومعاناة. واو يا له من إدمان! إزالة الحوامل والعصبية ، والأطفال من المراقبين ومرحبا بكم في الغواصة!
فلسفة
MAM هي تجربة جريئة لتغيير طريقة تنظيم الكود بطريقة جذرية وعملية التعامل معها. فيما يلي المبادئ الأساسية:
اتفاقيات بدلا من التكوين. تسمح لك الاتفاقيات المعقولة والبسيطة والعالمية بأتمتة كامل الروتين ، مع الحفاظ على الراحة والاتساق بين المشاريع المختلفة.
البنية التحتية منفصلة ، الرمز منفصل. الموقف ليس شائعًا عندما تحتاج إلى تطوير العشرات أو حتى مئات المكتبات والتطبيقات. لا تنشر البنية التحتية للتجميع والتطوير والنشر وما إلى ذلك لكل منهم. يكفي أن نطلبها مرة واحدة ثم برشام التطبيقات مثل الفطائر.
لا تدفع مقابل ما لا تستخدمه. يمكنك استخدام نوع من الوحدة النمطية - يتم تضمينه في الحزمة مع جميع التبعيات. لا تستخدم - لا يعمل. أصغر الوحدات ، وأكبر التفاصيل وأقل رمز لا لزوم لها في الحزمة.
الحد الأدنى من رمز زائدة عن الحاجة. يجب أن يكون تقسيم الشفرة إلى وحدات بسيطة مثل كتابة التعليمات البرمجية في ملف واحد. خلاف ذلك ، سيكون المطور كسولًا لتقسيم الوحدات الكبيرة إلى وحدات صغيرة.
لا يوجد تعارض في الإصدار. هناك إصدار واحد فقط - الإصدار الحالي. ليست هناك حاجة إلى إنفاق الموارد على دعم الإصدارات القديمة ، إذا كنت تستطيع إنفاقها على تحديث الإصدار الأخير.
إبقاء إصبع على النبض. إن ردود الفعل الأسرع فيما يتعلق بعدم التوافق لن تسمح للشفرة بأن تسوء.
أسهل طريقة هي الأضمن. إذا كان المسار الصحيح يتطلب بذل جهد إضافي ، فتأكد من عدم ذهاب أحد إليه.
الواردات / الصادرات
نفتح المشروع الأول الذي تم إنشاؤه باستخدام نظام وحدة نمطية حديث: الوحدة النمطية أقل من 300 سطر ، 30 منها عبارة عن واردات.
ولكن هذه لا تزال زهور: للحصول على وظيفة من 9 خطوط ، هناك حاجة إلى 8 واردات.
والمفضل لدي: ليس سطر واحد من التعليمات البرمجية المفيدة. 20 سطور لتحويل القيم من كومة من الوحدات النمطية إلى واحد ، بحيث يمكنك في وقت لاحق الاستيراد من وحدة واحدة ، وليس من عشرين.
كل هذا عبارة عن صفيحة ، مما يؤدي إلى حقيقة أن المطورين كسولون جدًا في تخصيص أجزاء صغيرة من الكود في وحدات منفصلة ، مفضلين الوحدات الكبيرة على الوحدات الصغيرة. وحتى إذا لم تكن كسولًا ، فإنه يظهر إما الكثير من التعليمات البرمجية لاستيراد الوحدات النمطية الصغيرة أو الوحدات النمطية الخاصة التي تستورد الكثير من الوحدات النمطية إلى نفسها وتصديرها جميعًا بكميات كبيرة.
كل هذا يؤدي إلى انخفاض دقة الشفرة وتضخيم حجم الحزم بالرمز غير المستخدم ، والذي يعتبر محظوظًا بدرجة كافية ليكون قريبًا من الحزم المستخدمة. بالنسبة إلى JS ، فهم يحاولون حل هذه المشكلة عن طريق تعقيد خط أنابيب التجميع ، عن طريق إضافة ما يسمى بـ "هز الأشجار" ، والذي يقطع الزائدة عن ما استوردته. هذا يبطئ التجمع ، ولكن ليس كل شيء يتم قطع.
الفكرة: ماذا لو لم نستورد ، ولكننا نأخذ ونستخدم فقط ، وسيكتشف الجامع نفسه ما الذي يجب استيراده؟
يمكن أن تنشئ IDEs الحديثة تلقائيًا واردات للكيانات التي تستخدمها. إذا كان بإمكان IDE القيام بذلك ، فما الذي يمنع المجمع من القيام بذلك؟ يكفي وجود اتفاقية بسيطة حول تسمية الملفات وموقعها ، والتي ستكون مناسبة للمستخدم ويمكن فهمها بالنسبة للجهاز. PHP لديها منذ فترة طويلة مثل هذه الاتفاقية القياسية: PSR-4 . يقدم MAM نفس الشيء لملفات .ts و .jam.js: الأسماء التي تبدأ بـ $ هي الاسم المؤهل بالكامل لبعض الكيانات العمومية التي يتم تحميل رمزها على طول المسار الذي تم الحصول عليه من FQN عن طريق استبدال المحددات بشرطة مائلة. مثال بسيط على وحدتين:
my / alert / alert.ts
const $my_alert = alert // FQN
my / app / app.ts
$my_alert( 'Hello!' ) // , /my/alert/
وحدة كاملة من سطر واحد - ماذا يمكن أن يكون أكثر بساطة؟ النتيجة ليست طويلة في المستقبل: بساطة إنشاء واستخدام الوحدات النمطية يؤدي إلى تقليل حجمها. نتيجة لذلك ، لتحقيق أقصى قدر من التفاصيل. ومثل الكرز - تقليل حجم الحزم دون أي هز الأشجار.
مثال جيد على ذلك هو JSON / mol / data من وحدات التحقق من الصحة. إذا كنت تستخدم وظيفة $mol_data_integer
في مكان ما في الكود ، $mol_data_integer
/mol/data/integer
و /mol/data/number
، التي يعتمد $mol_data_integer
، في الحزمة. ولكن ، على سبيل المثال ، لن يقرأ المجمّع /mol/data/email
حتى من القرص ، حيث لا أحد يعتمد عليه.
يخدع الفوضى
منذ أن بدأنا الركل الزاوي ، لن نتوقف. أين تظن أنك تبحث عن applyStyles
الدالة applyStyles
؟ لن /packages/core/src/render3/styling_next/bindings.ts
في /packages/core/src/render3/styling_next/bindings.ts
. تؤدي القدرة على وضع أي شيء في أي مكان إلى حقيقة أننا نلاحظ في كل مشروع نظامًا فريدًا لموقع الملفات ، غالبًا ما يكون غير قابل لأي منطق. وإذا تم حفظ IDE غالبًا عن طريق "الانتقال إلى التعريف" ، فسيتم حرمانك من عرض هذه الفرصة عند عرض الرمز على github أو مراجعة طلب السحب.
الفكرة: ماذا لو كانت أسماء الكيانات تتوافق بدقة مع مواقعها؟
لوضع الشفرة في الملف /angular/packages/core/src/render3/stylingNext/bindings.ts
، في بنية MAM ، سيتعين عليك تسمية الكيان $angular_packages_core_src_render3_stylingNext_applyStyles
، نظرًا لوجود الكثير من الأسماء في الاسم. لكن الأسماء في الكود التي أرغب في رؤيتها قصيرة ومختصرة ، لذلك سيحاول المطور استبعاد كل $angular_render3_applyStyles
غير الضرورية من الاسم ، مع ترك الأهمية فقط: $angular_render3_applyStyles
. وسوف يكون موجودا وفقا لذلك في /angular/render3/applyStyles/applyStyles.ts
.
لاحظ كيف تستخدم MAM نقاط ضعف المطورين لتحقيق النتيجة المرجوة: يحصل كل كيان على اسم فريد قصير عالميًا يمكن استخدامه في أي سياق. على سبيل المثال ، في رسائل التعهدات ، تتيح لك هذه الأسماء التقاط ما يتحدثون عنه بسرعة وبدقة:
73ebc45e517ffcc3dcce53f5b39b6d06fc95cae1 $mol_vector: range expanding support 3a843b2cb77be19688324eeb72bd090d350a6cc3 $mol_data: allowed transformations 24576f087133a18e0c9f31e0d61052265fd8a31a $mol_data_record: support recursion
أو دعنا نقول أنك تريد العثور على جميع الإشارات إلى وحدة mol_fiber $ على الإنترنت - مما يجعلها أسهل من أي وقت مضى بفضل FQN.
التبعيات الدورية
دعنا نكتب 7 سطور من الكود البسيط في ملف واحد:
export class Foo { get bar() { return new Bar(); } } export class Bar extends Foo {} console.log(new Foo().bar);
على الرغم من الاعتماد الدوري ، فإنه يعمل بشكل صحيح. نقسمها إلى 3 ملفات:
my / foo.js
import { Bar } from './bar.js'; export class Foo { get bar() { return new Bar(); } }
my / bar.js
import { Foo } from './foo.js'; export class Bar extends Foo {}
my / app.js
import { Foo } from './foo.js'; console.log(new Foo().bar);
عفوًا ، ReferenceError: Cannot access 'Foo' before initialization
. أي نوع من الهراء؟ لإصلاح هذا الأمر ، يجب أن يعرف app.js
لدينا أن foo.js
يعتمد على bar.js
لذلك ، نحتاج أولاً إلى استيراد bar.js
، والتي تستورد foo.js
بعد ذلك يمكننا استيراد foo.js
بالفعل دون خطأ:
my / app.js
import './bar.js'; import { Foo } from './foo.js'; console.log(new Foo().bar);
أن المتصفحات ، و NodeJS ، و Webpack ، و Parcel - تعمل جميعها بشكل متعرج مع تبعيات دائرية. حسناً ، كانوا ببساطة يمنعونهم - يمكن للمرء أن يعقد الشفرة على الفور حتى لا توجد حلقات. لكنهم يستطيعون العمل بشكل جيد ، ثم بام ، وإعطاء خطأ غير مفهوم.
الفكرة: ماذا لو أننا خلال التجميع ، قمنا فقط بلصق الملفات بالترتيب الصحيح ، كما لو كان كل الكود مكتوبًا في الأصل في ملف واحد؟
لنقسم الكود باستخدام مبادئ MAM:
my / foo / foo.ts
class $my_foo { get bar() { return new $my_bar(); } }
بلدي / شريط / bar.ts
class $my_bar extends $my_foo {}
my / app / app.ts
console.log(new $my_foo().bar);
كل نفس 7 سطور من التعليمات البرمجية التي كانت في الأصل. وهم يعملون فقط دون شامانية إضافية. الشيء هو أن المجمع يفهم أن اعتماد my/bar
على my/foo
أكثر صرامة من my/foo
على my/bar
. هذا يعني أنه يجب عليك تضمين هذه الوحدات في الحزمة بهذا الترتيب: my/foo
، my/bar
، my/app
.
كيف يفهم الجامع هذا؟ الآن إرشادي بسيط - بعدد المسافة البادئة في السطر الذي يتم فيه اكتشاف التبعية. يرجى ملاحظة أن الاعتماد الأقوى في مثالنا ليس به مسافة بادئة صفرية ، وأن ضعيف المسافة البادئة له مسافة بادئة مزدوجة.
لغات مختلفة
لقد حدث أن شحذ لغات مختلفة لهذه الأشياء المختلفة. من أكثرها شيوعًا: JS و TS و CSS و HTML و SVG و SCSS و Less و Stylus. لكل منها نظام الوحدة الخاص به ، والذي لا يتفاعل مع اللغات الأخرى بأي طريقة. وغني عن القول ، حوالي 100500 أنواع من لغات أكثر تحديدا. نتيجة لذلك ، من أجل توصيل أحد المكونات ، يجب عليك توصيل البرامج النصية الخاصة به بشكل منفصل ، والأنماط المنفصلة ، وقوالب التسجيل بشكل منفصل ، وتكوين نشر الملفات الثابتة التي يحتاجها ، بشكل منفصل ، إلخ.
بفضل اللوادر ، تحاول Webpack حل هذه المشكلة. ولكن لديه نقطة دخول هو البرنامج النصي الذي يربط الملفات بلغات أخرى بالفعل. وإذا كنا لا نحتاج إلى برنامج نصي؟ على سبيل المثال ، لدينا وحدة نمطية بها أنماط جميلة للوحات ونريد أن يكون لها نفس الألوان في النسق الفاتح وغيرها في الظلام:
.dark-theme table { background: black; } .light-theme table { background: white; }
علاوة على ذلك ، إذا كنا نعتمد على الموضوع ، فيجب أن يتم تحميل البرنامج النصي الذي سيقوم بتثبيت الموضوع المطلوب وفقًا للوقت من اليوم. وهذا هو ، CSS يعتمد في الواقع على JS.
الفكرة: ماذا لو كان النظام المعياري لا يعتمد على اللغات؟
نظرًا لأنه في MAM يتم فصل النظام المعياري عن اللغات ، ويمكن أن تكون التبعيات لغة مشتركة. قد يعتمد CSS على JS ، والذي قد يعتمد على TS ، والذي قد يعتمد على JS آخر. يتم تحقيق ذلك نظرًا لاكتشاف تبعيات المصدر على الوحدات النمطية ، ويتم توصيل الوحدات بالكامل ويمكن أن تحتوي على أكواد مصدر بأي لغة. في حالة مثال السمات ، يبدو كما يلي:
/my/table/table.css
[my_theme="dark"] table { background: black; } [my_theme="light"] table { background: white; }
/my/theme/theme.js
document.documentElement.setAttribute( 'my_theme' , ( new Date().getHours() + 15 ) % 24 < 12 ? 'light' : 'dark' , )
باستخدام هذه التقنية ، بالمناسبة ، يمكنك تطبيق Modernizr الخاص بك ، ولكن بدون 300 شيكات لا تحتاج إليها ، لأنه سيتم تضمين فقط تلك الشيكات التي يعتمد عليها CSS حقًا في الحزمة.
العديد من المكتبات
عادةً ما تكون نقطة الدخول لإنشاء حزمة هي نوع من الملفات. في حالة Webpack ، هذا هو JS. إذا قمت بتطوير الكثير من المكتبات والتطبيقات القابلة للتصرف ، فأنت بحاجة إلى الكثير من الحزم. ولكل حزمة تحتاج إلى إنشاء نقطة دخول منفصلة. في حالة Parcel ، تكون نقطة الدخول هي HTML ، والتي يجب إنشاء التطبيقات على أي حال. لكن بالنسبة للمكتبات ، فهذا غير مناسب إلى حد ما.
الفكرة: ما إذا كان يمكن تجميع أي وحدة في حزمة مستقلة دون تحضير أولي؟
دعونا نضع أحدث إصدار من منشئ مشروع MAM_build $ mol_build:
mam mol/build
قم الآن بتشغيل هذا المجمع واسمح له بالتجميع مرة أخرى للتأكد من أنه لا يزال قادرًا على تجميع نفسه:
node mol/build/-/node.js mol/build
على الرغم من ، لا ، دعنا نطلب منه إجراء الاختبارات مع الجمعية:
node mol/build/-/node.test.js mol/build
وإذا سارت الأمور على ما يرام ، انشر النتيجة في NPM:
npm publish mol/build/-
كما ترون ، عند تجميع الوحدة النمطية ، يتم إنشاء دليل فرعي بالاسم -
ويتم وضع جميع عناصر التجميع هناك. دعنا نذهب من خلال الملفات التي يمكنك العثور عليها هناك:
web.dep.json
- جميع المعلومات حول الرسم البياني التبعيةweb.js
- حزمة البرامج النصية للمستعرضweb.js.map
- sorsmaps لهweb.esm.js
- إنه في شكل وحدة نمطيةweb.esm.js.map
- و sorsmaps لذلكweb.test.js
- حزمة الاختبارweb.test.js.map
- ول اختبارات sorsmapweb.d.ts
- حزمة مع أنواع كل شيء موجود في حزمة البرامج النصيةweb.css
- حزمة مع الأنماطweb.css.map
- وتصنيفات لهاweb.test.html
- نقطة إدخال لتشغيل اختبارات الأداء في المستعرضweb.view.tree
- تعريفات لكافة المكونات المضمّنة في حزمة view.treeweb.locale=*.json
- حزم مع النصوص المترجمة ، كل حزمة لها حزمة خاصة بهاpackage.json
- يسمح لك بنشر الوحدة النمطية المجمعة فورًا في NPMnode.dep.json
- جميع المعلومات حول الرسم البياني التبعيةnode.js
- حزمة البرمجة النصية للعقدةnode.js.map
- sorsmaps لذلكnode.esm.js
- في شكل وحدة نمطيةnode.esm.js.map
- و sorsmaps لذلكnode.test.js
- نفس الحزمة ، ولكن أيضًا مع الاختباراتnode.test.js.map
- و sorsmaps لذلكnode.d.ts
- حزمة مع أنواع كل شيء موجود في حزمة البرامج النصيةnode.view.tree
- تعريفات لجميع المكونات المضمنة في حزمة view.treenode.locale=*.json
- حزم مع النصوص المترجمة ، كل حزمة لها حزمة خاصة بها
يتم نسخ احصائيات ببساطة جنبا إلى جنب مع المسارات. كمثال ، خذ تطبيقًا يعرض أكواد المصدر الخاصة به . مصادرها هنا:
/mol/app/quine/quine.view.tree
/mol/app/quine/quine.view.ts
/mol/app/quine/index.html
/mol/app/quine/quine.locale=ru.json
لسوء الحظ ، في الحالة العامة ، لا يستطيع المجمع معرفة أننا سنحتاج إلى هذه الملفات في وقت التشغيل. ولكن يمكننا أن نقول له هذا عن طريق وضع ملف خاص في مكان قريب:
/mol/app/quine/quine.meta.tree
deploy \/mol/app/quine/quine.view.tree deploy \/mol/app/quine/quine.view.ts deploy \/mol/app/quine/index.html deploy \/mol/app/quine/quine.locale=ru.json
نتيجة للتجميع /mol/app/quine
، سيتم نسخها بالطرق التالية:
/mol/app/quine/-/mol/app/quine/quine.view.tree
/mol/app/quine/-/mol/app/quine/quine.view.ts
/mol/app/quine/-/mol/app/quine/index.html
/mol/app/quine/-/mol/app/quine/quine.locale=ru.json
الآن ، يمكن وضع الدليل /mol/app/quine/-
على أي استضافة ثابتة وسيعمل التطبيق بالكامل.
JS يمكن تنفيذها على كل من العميل وعلى الخادم. وكم هو رائع عندما يمكنك كتابة رمز واحد وستعمل في كل مكان. ومع ذلك ، في بعض الأحيان يكون تنفيذ نفس الشيء على العميل والخادم مختلفًا تمامًا. وأريد ، على سبيل المثال ، تطبيق واحد ليتم استخدامه لعقدة ، والآخر للمتصفح.
الفكرة: ما إذا كان الغرض من الملف ينعكس في اسمه؟
يستخدم MAM نظام علامات في أسماء الملفات. على سبيل المثال ، توفر الوحدة النمطية $mol_state_arg
الوصول إلى معلمات التطبيق المعرفة من قبل المستخدم. في المستعرض ، يتم تعيين هذه المعلمات عبر شريط العناوين. وفي العقدة ، من خلال وسيطات سطر الأوامر. $mol_sate_arg
بقية التطبيق من هذه الفروق الدقيقة عن طريق تطبيق كلا الخيارين بواجهة واحدة ، ووضعهما في ملفات:
- / mol / state / arg / arg. الويب .ts - تنفيذ للمتصفحات
- / mol / state / arg / arg. العقدة .ts - تنفيذ العقدة
يتم تضمين المصادر غير الموسومة بهذه العلامات بغض النظر عن النظام الأساسي الهدف.
يتم ملاحظة موقف مشابه مع الاختبارات - فهي تريد أن يتم تخزينها بجوار باقي المصادر ، لكنها لا تريد تضمينها في الحزمة التي تذهب إلى المستخدم النهائي. لذلك ، يتم تعليم الاختبارات أيضًا بعلامة منفصلة:
- / mol / state / arg / arg. test .ts - اختبارات الوحدة ، سوف تقع في حزمة الاختبار
يمكن أن تكون العلامات حدودي. على سبيل المثال ، مع كل وحدة نمطية النصوص في لغات مختلفة يمكن أن تأتي ويجب أن تدرج في حزم اللغات المقابلة. الملف النصي هو قاموس JSON منتظم يحمل اسم الإعدادات المحلية بالاسم:
- / مول / التطبيق / الحياة / الحياة. الإعدادات المحلية = رو. json - النصوص للغة الروسية
- / مول / التطبيق / الحياة / الحياة. الإعدادات المحلية = jp .json - النصوص للغة اليابانية
أخيرًا ، ماذا لو أردنا وضع الملفات في مكان قريب ، لكننا نريد من التجميع تجاهلها وعدم تضمينها تلقائيًا في الحزمة؟ يكفي أن تضيف في بداية اسمها أي حرف غير أبجدي رقمي. على سبيل المثال:
- / هيو / لعب / . بوابة - تبدأ بفترة ، لذلك سيتجاهل المجمع هذا الدليل
الإصدارات
أصدرت Google لأول مرة AngularJS ونشرتها في NPM على أنها angular
. ثم قام بإنشاء إطار جديد تمامًا يحمل اسمًا مشابهًا - Angular ونشره بنفس الاسم ، لكن بالفعل الإصدار 2. الآن تتطور هاتان الألعاب النارية بشكل مستقل. يحدث تغيير واجهة برمجة التطبيقات واحد فقط بين الإصدارات الرئيسية. والآخر - بين القاصر . ونظرًا لأنه من المستحيل وضع نسختين من نفس التبعية على نفس المستوى ، فلا يمكن الحديث عن أي انتقال سلس ، عندما يتعايش نسختان من المكتبة في وقت واحد لبعض الوقت في التطبيق.
يبدو أن فريق Angular قد صعد بالفعل على جميع أشعل النار. وأكثر شيء واحد: يتم تقسيم رمز الإطار إلى عدة وحدات كبيرة. في البداية قاموا بإصدارها بشكل مستقل ، لكنهم حتى سريعًا بدأوا في الخلط بين إصدارات الوحدات النمطية التي تتوافق مع بعضها البعض ، ناهيك عن المطورين العاديين. لذلك ، تحولت Angular إلى إصدار من طرف إلى طرف ، حيث يمكن أن يتغير الإصدار الرئيسي من الوحدة حتى بدون أي تغييرات في الكود. يعد دعم إصدارات متعددة من الوحدات النمطية مشكلة كبيرة لكل من المشرفين أنفسهم وللنظام البيئي ككل. بعد كل شيء ، يتم إنفاق الكثير من الموارد لجميع أفراد المجتمع على ضمان التوافق مع الوحدات القديمة.
تنقسم الفكرة الجميلة المتمثلة في Semantic Versioning إلى واقع قاسٍ - فأنت لا تعرف أبدًا ما إذا كان هناك شيء ما سينكسر عند تغيير الإصدار الثانوي أو حتى إصدار التصحيح . لذلك ، في العديد من المشاريع ، يتم إصلاح إصدار محدد من التبعية. ومع ذلك ، لا يؤثر هذا الإصلاح على التبعيات العابرة ، والتي قد يتم استخلاصها إلى أحدث إصدار عند التثبيت من نقطة الصفر ، ولكنها قد تظل كما هي إذا كانت مثبتة بالفعل. تؤدي هذه الفوضى إلى حقيقة أنه لا يمكنك أبدًا الاعتماد على إصدار ثابت وتحتاج إلى التحقق بانتظام من التوافق مع الإصدارات الحالية من التبعيات (على الأقل متعدية).
ولكن ماذا عن قفل الملفات ؟ إذا كنت تقوم بتطوير مكتبة مثبتة من خلال التبعيات ، فلن يساعدك ملف القفل ، لأن مدير الحزمة سيتجاهلها. بالنسبة للتطبيق النهائي ، سيمنحك ملف القفل ما يسمى "استنساخ التجميعات". ولكن دعونا نكون صادقين. كم مرة تحتاج إلى إنشاء التطبيق النهائي من نفس المصدر؟ بالضبط مرة واحدة. تلقي الإخراج ، بغض النظر عن أي NPM ، قطعة أثرية التجميع: ثنائي قابل للتنفيذ ، حاوية الإرساء أو مجرد أرشيف مع جميع التعليمات البرمجية اللازمة لتشغيله. آمل أنك لا تفعل npm install
على همز؟
يجد البعض استخدام ملفات القفل لجعل خادم CI يقوم بتجميع ما التزم به المطور تمامًا. لكن انتظر ، يمكن للمطور نفسه تجميعه ببساطة على الجهاز المحلي الخاص به. , , , . Continuous Integration , , , , - . CI , .
, , . , Angular@4 ( 3). , , " " " ". Angular@4 , Angular@5. Angular@6, . Angular TypeScript . . , 2 , … , business value , , , , .
, , , , 2 . : , — , — . 3 React, 5 jQuery, 7 lodash.
: — ?
. - . , . , . , . , . , . , , . : issue, , workaround, pull request, , . , , . . .
, . , , . . . : , , -. - — . , , - . , , , NPM . , . .
, ? — . mobx
, mobx2
API . — , : , . mobx
mobx2
, API. API, .
. — . , :
var pages_count = $mol_atom2_sync( ()=> $lib_pdfjs.getDocument( uri ).promise ).document().numPages
mol_atom2_sync
lib_pdfjs
, :
npm install mol_atom2_sync@2.1 lib_pdfjs@5.6
, , — , . ? — , *.meta.tree
, :
/.meta.tree
pack node git \https://github.com/nin-jin/pms-node.git pack mol git \https://github.com/eigenmethod/mol.git pack lib git \https://github.com/eigenmethod/mam-lib.git
. .
NPM
MAM — NPM . , — . , , NPM .
NPM , $node. , - -:
/my/app/app.ts
$node.portastic.find({ min : 8080 , max : 8100 , retrieve : 1 }).then( ( ports : number[] ) => { $node.express().listen( ports[0] ) })
, . - lib
NPM . , NPM- pdfjs-dist
:
/lib/pdfjs/pdfjs.ts
namespace $ { export let $lib_pdfjs : typeof import( 'pdfjs-dist' ) = require( 'pdfjs-dist/build/pdf.min.js' ) $lib_pdfjs.disableRange = true $lib_pdfjs.GlobalWorkerOptions.workerSrc = '-/node_modules/pdfjs-dist/build/pdf.worker.min.js' }
/lib/pdfjs/pdfjs.meta.tree
deploy \/node_modules/pdfjs-dist/build/pdf.worker.min.js
, .
. create-react-app
angular-cli
, . , , eject
. . , , .
: ?
MAM . .
MAM MAM , :
git clone https://github.com/eigenmethod/mam.git ./mam && cd mam npm install npm start
8080 . , — MAM.
( — acme
) ( — hello
home
):
/acme/acme.meta.tree
pack hello git \https://github.com/acme/hello.git pack home git \https://github.com/acme/home.git
npm start
:
npm start acme/hello acme/home
. — . , , . — : https://t.me/mam_mol