في آخر ثلاث أو أربع سنوات ، عند البرمجة بلغة PHP ، استخدمت composer
لإدارة تبعيات التطبيق. الآن هناك حاجة إلى التبديل إلى nodejs
، ونتيجة لذلك ، تكوين بيئة تطوير مألوفة. لحسن الحظ ، أنا أستخدم PhpStorm IDE ، والذي يسمح لك بالعمل مع كل من PHP و JS. من سمات المشاريع التي أشارك فيها تعددية الوحدات. يتم تقسيم الوظيفة بين الوحدات النمطية ليس لإعادة استخدامها بقدر ما تقلل من التعقيد النهائي للتطبيق بسبب التحلل إلى مكونات متراصة. بشكل عام ، من الطبيعي بالنسبة لهذه المشروعات عندما يتم إجراء تغييرات على عدة وحدات وتلتزم بعدة مستودعات في إطار حل مشكلة واحدة.

عند إعداد مشروع nodejs
، صادفت بعض الميزات التي تُعقِّد التطوير متعدد الوحدات. ولد هذا المنشور في محاولة للتعامل مع هذه الميزات. تحت القص ، ينظر PHP إلى نشر مشروع nodejs
.
هيكل المشروع التجريبي
يتكون المشروع من 3 وحدات:
- التطبيق : رئيس وحدة ربط التبعيات.
- الوحدة الوظيفية : تحتوي على وظائف تسمى من وحدة الرأس ؛
- الوحدة النمطية الأساسية : تحتوي على وظائف تسمى من وحدة نمطية دالة ؛

يقع رمز كل وحدة نمطية على جيثب:
توجد واصفات الوحدة النمطية لمديري التبعية المعنيين ( composer.json
و package.json
) في كل وحدة ، أي ، يمكن توسيع كل وحدة كوحدة نمطية php وكوحدة js. يتم وضع كود PHP ورمز JS في الوحدات ببساطة جنبًا إلى جنب ، دون تقاطع بعضهما البعض.
تشغيل التطبيق للتنفيذ:
$ php index.php $ nodejs index.js
نتيجة العمل في كلتا الحالتين:
This is application. This is func module. This is base module.
أهداف
يجب أن يسمح المشروع في بيئة العمل بما يلي:
- تتبع التغييرات IDE في كل وحدة تشارك في التطوير ؛
- باستخدام IDE ، قم بإجراء تغييرات على مستودعات مختلفة في إجراء واحد.
- استخدام المصحح لتتبع تنفيذ التعليمات البرمجية من الوحدات النمطية ؛
نشر من خلال composer
كل شيء مألوف هنا. في واصف النشر ( composer.json ) للتطبيق ، حدد عناوين المستودعات التي تحتوي على وحدات ووصف الفروع الرئيسية للوحدات النمطية باعتبارها تبعيات مع الإصدار المطلوب:
{ "require": { "flancer64/habr-cvsn-mod-base": "dev-master as 0.1.0", "flancer64/habr-cvsn-mod-func": "dev-master as 0.1.0" }, "repositories": [ { "type": "vcs", "url": "https://github.com/flancer64/habr-cvsn-mod-base" }, { "type": "vcs", "url": "https://github.com/flancer64/habr-cvsn-mod-func" } ] }
بعد تنفيذ الأمر:
$ composer install
تظهر ./vendor
مع الوحدات النمطية في دليل ./vendor
، والذي بدوره يحتوي على أدلة .git
:
./vendor/
./flancer64/
./habr-cvsn-mod-base/
./habr-cvsn-mod-base/
أي أن composer
ينشر على الفور التبعيات في شكل مناسب للتطوير (التحكم في الإصدار). يبقى فقط لتكوين PhpStorm IDE (وضع الوحدات التابعة تحت التحكم في الإصدار):

ويمكنك تتبع التغييرات في جميع الوحدات المتقدمة:

وإلزام جميع التغييرات على المستودعات المحلية في نفس الوقت:

ودفع إلى بعيد:

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

بشكل عام ، البيئة المعتادة ، مريحة مثل النعال.
النشر العادي من خلال npm
على عكس composer
لا تفترض npm
أنه في المشروع ، قد تكون أي وحدات من دليل node_modules
تحت تحكم الإصدار. يمكننا تحديد في حزمة واصف النشر. json أنه يجب تحميل الوحدة من مستودع خارجي (على سبيل المثال ، من githib):
{ "dependencies": { "habr-cvsn-mod-base": "github:flancer64/habr-cvsn-mod-base", "habr-cvsn-mod-func": "github:flancer64/habr-cvsn-mod-func" } }
لكن ليس لدينا خيار إنشاء npm
لإنشاء مستودع محلي للوحدة النمطية المحملة (دليل فرعي .git
).
بعد تنفيذ الأمر:
$ npm install
يتم تنزيل التبعيات وتثبيتها محليًا دون إمكانية استخدام التحكم في الإصدار:

(دليل فرعي مفقود. / ./.git/
in ./node_modules/habr-cvsn-mod-base/
)
لكن المصحح يتوقف في الوحدة النمطية الأساسية دون مشاكل:

نشر عبر npm باستخدام خيار الارتباط
بحيث يمكن الاحتفاظ ./node_modules/
النمطية من ./node_modules/
تحت التحكم في الإصدار ، يقترح مطورو npm
استخدام الخيار " link ". باختصار ، فإن جوهر النهج هو أن الوحدات التي تحتاج إلى إصدار يتم استنساخها إلى مكان تعسفي على قرص المطور (على سبيل المثال ، في /home/alex/work/habr/
) ، ثم ترتبط بـ /usr/lib/node_modules/
باستخدام الأمر:
# npm link
(كنت بحاجة إلى امتيازات الجذر للتنفيذ)
بعد ذلك ، يمكنك بالفعل استخدام الأوامر في المشروع:
$ npm link habr-cvsn-mod-base $ npm link habr-cvsn-mod-func
سوف تجد npm
الوحدات النمطية المناسبة في /usr/lib/node_modules/
وتغلق الدلائل الفرعية المقابلة من مشروع ./node_modules/
لهم:
$ ls -lh ./node_modules/ total 0 lrwxrwxrwx 1 alex alex 57 jūl 2 16:18 habr-cvsn-mod-base -> ../../../../../../usr/lib/node_modules/habr-cvsn-mod-base lrwxrwxrwx 1 alex alex 57 jūl 2 16:18 habr-cvsn-mod-func -> ../../../../../../usr/lib/node_modules/habr-cvsn-mod-func
الوحدات في /usr/lib/node_modules/
بحد ذاتها ، هي روابط إلى الموقع الأصلي للوحدات النمطية:
$ ls -lh /usr/lib/node_modules/ ... lrwxrwxrwx 1 root root 39 jūl 2 16:18 habr-cvsn-mod-base -> /home/alex/work/habr/habr-cvsn-mod-base lrwxrwxrwx 1 root root 39 jūl 2 16:18 habr-cvsn-mod-func -> /home/alex/work/habr/habr-cvsn-mod-func ...
وفي مكانهم الدائم ، يحتوي "التسجيل" على مستودع محلي:
$ ls -lha /home/alex/work/habr/habr-cvsn-mod-base ... drwxrwxr-x 8 alex alex 4,0K jūl 2 16:18 .git ...
وبالتالي ، يمكننا تكوين IDE للتحكم في التغييرات في تبعيات المشروع:

تبدأ المشاكل عند محاولة تشغيل التطبيق:
$ nodejs index.js internal/modules/cjs/loader.js:670 throw err; ^ Error: Cannot find module 'habr-cvsn-mod-base' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15) at Function.Module._load (internal/modules/cjs/loader.js:591:27) at Module.require (internal/modules/cjs/loader.js:723:19) at require (internal/modules/cjs/helpers.js:14:16) at Object.<anonymous> (/home/alex/work/habr/habr-cvsn-mod-func/src/index.js:3:14) ...
يرى التطبيق الوحدة الوظيفية المرتبطة ، لكن الوحدة الوظيفية نفسها لا ترى الوحدة الأساسية المرتبطة. للخروج من الموقف ، استخدم مفتاح - Preserve-symlinks nodejs
:
$ nodejs --preserve-symlinks index.js
أضف المفتاح إلى أمر إطلاق المشروع في IDE:

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

يقول مطورو IDE إنه يجب أن يعمل ، لكنه لا يعمل (ذاكرة التخزين المؤقت التي تمت إزالتها ، وتم إعادة تشغيل IDE).
بشكل عام ، كان الغرض من هذا المنشور هو إجراء مقابلات مع زملائه عن كيفية الخروج في وضع مماثل ، ولكن أثناء كتابة المقالة ، ظهر مزيج آخر لتطوير المشروع:
وضع شفرات المصدر في الدلائل الداخلية لمشروع npm
اتضح أنه إذا كنت تستخدم الارتباط ، يمكنك استخدام نسخ من الوحدات النمطية من github التي تم إنشاؤها بواسطة composer
في الدليل الفرعي ./vendor/
، بدلاً من ربطها ./vendor/
خارجية للمشروع ، ثم يتم تشغيل البرامج النصية js بدون --preserve-symlinks
، و الأهم من ذلك بالنسبة لي ، فإن PhpStorm IDE يرى نقاط توقف داخل الوحدات. لأن ليس من المنطقي استخدام composer
فقط لوحدات استنساخ المشروع ، فقد استخدمت git
المعتادة واستنسخت الكود المصدري للوحدات النمطية في الدليل الفرعي ./own_modules
. ثم كرر التلاعب من الفقرة السابقة:
- ربط الوحدات النمطية في الدليل الفرعي.
./own_modules/...
بمكتبة النظام /usr/lib/node_modules/
؛ - وحدات متصلة في مكتبة النظام مع المشروع ؛
- تكوين IDp PhpStorm للعمل مع المستودعات المحلية في الدليل الفرعي
./own_modules/
؛

لا أعرف السبب ، ولكن عندما تكون مصادر الوحدات التابعة داخل المشروع ، فإن النتيجة النهائية للتجميع تختلف اختلافًا كبيرًا عن مصادر مصادر الوحدات التابعة في دليل خارج المشروع.
ملخص
مقارنة بين النهجين لبناء تطبيقات متعددة الوحدات (PHP مع composer
و JS مع npm
) ، يمكنني أن أستنتج أن composer
أكثر ملاءمة للمطور من npm
. من المحتمل أن مطوري composer
(الإصدار الأول في 2012) قد أخذوا في الاعتبار تجربة مطوري npm
(الإصدار الأول في 2010). ومع ذلك ، مع بعض الجهد الإضافي ، توفر npm
أيضًا الفرصة لتطوير تطبيقات متعددة الوحدات في ظروف مريحة إلى حد ما.
نصوص الأوامر لنشر المشروع في أوضاع مختلفة: