Dalam tiga atau empat tahun terakhir, ketika pemrograman dalam PHP, saya menggunakan composer
untuk mengelola dependensi aplikasi. Sekarang ada kebutuhan untuk beralih ke nodejs
dan, sebagai hasilnya, mengkonfigurasi lingkungan pengembangan yang sudah dikenal. Untungnya, saya menggunakan PhpStorm IDE, yang memungkinkan Anda bekerja dengan PHP dan JS. Fitur dari proyek di mana saya berpartisipasi adalah multi-modularitas. Fungsionalitas dibagi di antara modul-modul yang tidak begitu banyak digunakan kembali untuk mengurangi kompleksitas akhir aplikasi karena penguraian menjadi komponen yang digabungkan secara longgar. Secara umum, adalah normal untuk proyek-proyek ini ketika, dalam kerangka penyelesaian satu masalah, perubahan dilakukan pada beberapa modul dan berkomitmen untuk beberapa repositori.

Ketika mengatur proyek nodejs
, saya menemukan beberapa fitur yang menyulitkan pengembangan multi-modul. Publikasi ini lahir dalam proses mencoba menangani fitur-fitur ini. Di bawah potongan, tampilan PHP pada penggelaran proyek nodejs
.
Struktur Proyek Demo
Proyek ini terdiri dari 3 modul:
- aplikasi : modul kepala yang menghubungkan dependensi;
- modul fungsional : berisi fungsi-fungsi yang dipanggil dari modul kepala;
- modul dasar : berisi fungsi-fungsi yang dipanggil dari modul fungsi;

Kode untuk setiap modul terletak di github:
Deskriptor modul untuk masing-masing manajer dependensi ( composer.json
dan package.json
) terletak di setiap modul, yaitu, setiap modul dapat diperluas baik sebagai modul php maupun sebagai modul js. Kode PHP dan kode JS dalam modul hanya ditempatkan berdampingan, tanpa saling berpotongan.
Menjalankan aplikasi untuk dieksekusi:
$ php index.php $ nodejs index.js
Hasil kerja dalam kedua kasus:
This is application. This is func module. This is base module.
Tujuan
Sebuah proyek di lingkungan kerja harus memungkinkan:
- melacak perubahan IDE di setiap modul yang terlibat dalam pengembangan;
- Menggunakan IDE, lakukan perubahan pada repositori berbeda dalam satu tindakan.
- Gunakan debugger untuk melacak eksekusi kode modul;
Penempatan melalui composer
Semuanya akrab di sini. Dalam deskriptor penyebaran ( composer.json ) dari aplikasi, tentukan alamat repositori dengan modul dan tentukan cabang-cabang utama dari modul sebagai dependensi dengan versi yang diinginkan:
{ "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" } ] }
Setelah menjalankan perintah:
$ composer install
./vendor
dengan modul muncul di direktori ./vendor
, yang pada gilirannya berisi direktori .git
:
./vendor/
./flancer64/
./habr-cvsn-mod-base/
./habr-cvsn-mod-base/
Artinya, composer
segera menyebarkan dependensi dalam bentuk yang sesuai untuk pengembangan (kontrol versi). Tetap hanya untuk mengkonfigurasi IDE PhpStorm (meletakkan modul tergantung di bawah kontrol versi):

dan Anda dapat melacak perubahan di semua modul yang dikembangkan:

dan komit semua perubahan pada repositori lokal secara bersamaan:

dan dorong ke remote:

Debugging juga tidak masalah. Kita dapat mengatur breakpoint pada setiap baris kode modul dasar - setelah memulai aplikasi di bawah debugger, break terjadi jika perlu:

Secara umum, lingkungan yang biasa, senyaman sandal.
Penempatan normal hingga npm
Tidak seperti composer
npm
tidak menganggap bahwa dalam proyek modul apa pun dari direktori node_modules
mungkin di bawah kontrol versi. Kita dapat menentukan dalam deployment descriptor package.json bahwa modul harus diambil dari repositori eksternal (misalnya, dari githib):
{ "dependencies": { "habr-cvsn-mod-base": "github:flancer64/habr-cvsn-mod-base", "habr-cvsn-mod-func": "github:flancer64/habr-cvsn-mod-func" } }
tetapi kami tidak memiliki opsi untuk meminta npm
membuat repositori lokal untuk modul yang dimuat (subdirektori. .git
).
Setelah menjalankan perintah:
$ npm install
dependensi diunduh dan diinstal secara lokal tanpa kemungkinan menggunakan kontrol versi:

(tidak ada subdirektori ./.git/
dalam ./node_modules/habr-cvsn-mod-base/
)
Tetapi debugger berhenti di modul dasar tanpa masalah:

Sebarkan melalui npm menggunakan opsi tautan
Agar modul dari ./node_modules/
dapat disimpan di bawah kontrol versi, pengembang npm
menyarankan menggunakan opsi ' tautan '. Singkatnya, inti dari pendekatan ini adalah bahwa modul yang perlu diversi diklon ke tempat sewenang-wenang pada disk pengembang (misalnya, di /home/alex/work/habr/
), dan kemudian ditautkan ke /usr/lib/node_modules/
menggunakan perintah:
# npm link
(Saya membutuhkan hak akses root untuk menjalankan)
Setelah itu, Anda sudah dapat menggunakan perintah di proyek:
$ npm link habr-cvsn-mod-base $ npm link habr-cvsn-mod-func
npm
akan menemukan modul yang sesuai di /usr/lib/node_modules/
dan menutup subdirektori yang sesuai dari proyek ./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
Modul-modul di /usr/lib/node_modules/
sendiri, pada gilirannya, adalah tautan ke lokasi asli modul:
$ 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 ...
Dan di tempat permanen mereka, "pendaftaran" berisi repositori lokal:
$ ls -lha /home/alex/work/habr/habr-cvsn-mod-base ... drwxrwxr-x 8 alex alex 4,0K jūl 2 16:18 .git ...
Dengan demikian, kita dapat mengkonfigurasi IDE untuk mengontrol perubahan dalam dependensi proyek:

Masalah dimulai ketika Anda mencoba menjalankan aplikasi:
$ 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) ...
Aplikasi melihat modul fungsional tertaut, tetapi modul fungsional itu sendiri tidak melihat modul dasar tertaut. Untuk keluar dari situasi, gunakan kunci --preserve-symlinks untuk nodejs
:
$ nodejs --preserve-symlinks index.js
Tambahkan kunci ke perintah peluncuran proyek di IDE:

Sekarang peluncurannya berlalu, tetapi ada masalah dengan debugging - break point dalam dependensi tidak berhasil. Anda bisa berhenti di modul kepala dan turun langkah-langkah ke sumber-sumber ketergantungan, tetapi IDE PhpStorm tidak melihat breakpoint itu sendiri di runtime, meskipun itu menampilkan:

Pengembang IDE mengatakan bahwa itu harus bekerja, tetapi tidak berfungsi (cache memerah, IDE dihidupkan ulang).
Secara umum, tujuan publikasi ini adalah untuk mewawancarai kawan-kawan bagaimana mereka keluar dalam situasi yang sama, tetapi dalam proses penulisan artikel, kombinasi lain muncul untuk pengembangan proyek:
Penempatan kode sumber dalam direktori internal proyek npm
Ternyata jika untuk menghubungkan Anda menggunakan klon modul dari github yang dibuat oleh composer
di subdirektori ./vendor/
, alih-alih diikat ke direktori di luar proyek, maka skrip js dijalankan tanpa --preserve-symlinks
dan, lebih penting bagi saya, PhpStorm IDE melihat breakpoint di dalam modul. Karena tidak masuk akal untuk menggunakan composer
hanya untuk kloning modul proyek, saya menggunakan git
biasa dan mengkloning kode sumber modul ke subdirektori ./own_modules
. Kemudian dia mengulangi manipulasi dari paragraf sebelumnya:
- menghubungkan modul-modul dalam subdirektori
./own_modules/...
dengan pustaka sistem /usr/lib/node_modules/
; - modul yang terhubung di perpustakaan sistem dengan proyek;
- Mengkonfigurasi PhpStorm IDE agar berfungsi dengan repositori lokal di subdirektori
./own_modules/
;

Saya tidak tahu apa alasannya, tetapi ketika sumber modul dependen ada di dalam proyek, hasil akhir majelis sangat berbeda dari ketika sumber modul dependen berada di direktori di luar proyek.
Ringkasan
Membandingkan dua pendekatan untuk membangun aplikasi multi-modul (PHP dengan composer
dan JS dengan npm
), saya dapat menyimpulkan bahwa composer
lebih ramah pengembang daripada npm
. Ada kemungkinan bahwa pengembang composer
(rilis pertama pada 2012) memperhitungkan pengalaman pengembang npm
(rilis pertama pada 2010). Namun, dengan beberapa upaya tambahan, npm
juga memberikan kesempatan untuk mengembangkan aplikasi multi-modul dalam kondisi yang cukup nyaman.
Script perintah untuk penyebaran proyek dalam berbagai mode: