Haruskah saya memeriksa node_modules untuk git ketika membuat aplikasi node.js di Heroku?

368

Saya mengikuti instruksi dasar untuk memulai node.js di Heroku di sini:

https://devcenter.heroku.com/categories/nodejs

Instruksi ini tidak memberitahu Anda untuk membuat .gitignore node_modules, dan oleh karena itu menyiratkan bahwa node_modules harus diperiksa untuk git. Ketika saya memasukkan node_modules di git, aplikasi persiapan saya berjalan dengan benar.

Ketika saya mengikuti contoh yang lebih maju di:

https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio https://github.com/mongolab/tractorpush-server (sumber)

Itu menginstruksikan saya untuk menambahkan node_modules ke .gitignore. Jadi saya menghapus node_modules dari git, menambahkannya ke .gitignore, kemudian digunakan kembali. Kali ini yang digunakan gagal seperti:

-----> Heroku receiving push
-----> Node.js app detected
-----> Resolving engine versions
       Using Node.js version: 0.8.2
       Using npm version: 1.0.106
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
       Error: npm doesn't work with node v0.8.2
       Required: node@0.4 || 0.5 || 0.6
           at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
           at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
           at Module._compile (module.js:449:26)
           at Object.Module._extensions..js (module.js:467:10)
           at Module.load (module.js:356:32)
           at Function.Module._load (module.js:312:12)
           at Module.require (module.js:362:17)
           at require (module.js:378:17)
           at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
           at Module._compile (module.js:449:26)
       Error: npm doesn't work with node v0.8.2
       Required: node@0.4 || 0.5 || 0.6
           at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
           at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
           at Module._compile (module.js:449:26)
           at Object.Module._extensions..js (module.js:467:10)
           at Module.load (module.js:356:32)
           at Function.Module._load (module.js:312:12)
           at Module.require (module.js:362:17)
           at require (module.js:378:17)
           at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
           at Module._compile (module.js:449:26)
       Dependencies installed
-----> Discovering process types
       Procfile declares types -> mongod, redis, web
-----> Compiled slug size is 5.0MB
-----> Launching... done, v9

Menjalankan "heroku ps" mengkonfirmasi kerusakan itu. Ok, tidak masalah, jadi saya memutar kembali perubahan, menambahkan node_module kembali ke repositori git dan menghapusnya dari .gitignore. Namun, bahkan setelah kembali, saya masih mendapatkan pesan kesalahan yang sama pada penerapan tetapi sekarang aplikasi berjalan dengan benar lagi. Menjalankan "heroku ps" memberi tahu saya bahwa aplikasi sedang berjalan.

Jadi pertanyaan saya adalah apa cara yang benar untuk melakukan ini? Sertakan node_modules atau tidak? Dan mengapa saya masih mendapatkan pesan kesalahan saat saya mengembalikan? Tebakan saya adalah repositori git dalam kondisi buruk di sisi Heroku?

Jason Griffin
sumber
10
Saya adalah pemilik bahasa Node di Heroku dan jawabannya sederhana: Tidak. Jangan check- node_modulesin ke aplikasi Heroku.
hunterloftis
@ hunterloftis 'Jangan centang node_modules ke ' atau 'Jangan periksa node_modules ke '? Untuk memperjelas, sebagai pemilik bahasa Node di Heroku, apakah Anda ingin kami mengunggah seluruh node_modules kami melalui push git kami atau tidak? Saya lebih suka untuk tidak karena pemborosan bandwidth dan fakta bahwa Heroku akan mendapatkannya di backend dari git push saya; Namun, saya harus mengedit file di node_modules saya secara manual untuk membuat Heroku memuat aplikasi saya. Karena itu saya harus mengabaikan node_modules minus seluruh modul yang menyertakan file yang saya edit untuk membuatnya berfungsi.
ZStoneDPM

Jawaban:

400

Pembaruan Kedua

FAQ tidak tersedia lagi.

Dari dokumentasi shrinkwrap:

Jika Anda ingin mengunci byte spesifik yang termasuk dalam paket, misalnya memiliki kepercayaan 100% untuk dapat mereproduksi penyebaran atau membangun, maka Anda harus memeriksa dependensi Anda ke dalam kontrol sumber, atau mengejar beberapa mekanisme lain yang dapat memverifikasi konten daripada versi.

Shannon dan Steven menyebutkan ini sebelumnya, tetapi saya pikir, itu harus menjadi bagian dari jawaban yang diterima.


Memperbarui

Sumber yang tercantum untuk rekomendasi di bawah ini telah diperbarui . Mereka tidak lagi merekomendasikan node_modulesfolder tersebut dikomit.

Biasanya tidak. Izinkan npm untuk menyelesaikan dependensi untuk paket Anda.

Untuk paket yang Anda gunakan, seperti situs web dan aplikasi, Anda harus menggunakan npm shrinkwrap untuk mengunci pohon ketergantungan penuh Anda:

https://docs.npmjs.com/cli/shrinkwrap


Pos Asli

Untuk referensi, npm FAQ menjawab pertanyaan Anda dengan jelas:

Periksa node_modules ke git untuk hal-hal yang Anda gunakan, seperti situs web dan aplikasi. Jangan periksa node_modules ke git untuk pustaka dan modul yang dimaksudkan untuk digunakan kembali. Gunakan npm untuk mengelola dependensi di lingkungan dev Anda, tetapi tidak di skrip penerapan Anda.

dan untuk alasan yang bagus untuk ini, baca posting Mikeal Rogers tentang ini .


Sumber: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git

Kostia
sumber
13
Ini tidak benar - sebenarnya itu ide yang sangat buruk. Jika Anda mengembangkan pada Windows kemudian menggunakan di Linux, Anda harus membangun kembali node_modules ketika Anda menggunakan. Yang berarti - kekacauan. Banyak file yang dimodifikasi, dan tidak tahu harus berbuat apa.
user3690202
8
Itu tidak mungkin - beberapa pengembang kami mengembangkan windows penargetan, yang lain menargetkan linux, tetapi basis kode yang sama. Pendekatan terbaik adalah dengan tidak melakukan modul node - oops.
user3690202
7
@ user3690202 Kedengarannya Anda memiliki kasus yang sangat tidak konvensional, daripada norma, jadi mengatakan "ini tidak benar" mungkin terlalu berlebihan. Karena itu, tidak yakin apa kasus penggunaan Anda sebenarnya, tapi saya tidak bisa memikirkan alasan untuk menggunakan windows dan linux untuk pengembangan. Tetap berpegang pada satu, dan jalankan tes atau QA pada semua platform dukungan Anda.
Kostia
16
@Kostia Kasing penggunaan kami cukup umum. Kami adalah sukarelawan dan menggunakan mesin kami sendiri, bukan mesin perusahaan. Sepertinya situasi yang cukup umum untuk open source.
Adam
4
@Adam secara tangensial, dapatkah Anda menambahkan file yang sedang dikompilasi .gitignore? Dengan begitu, sumbernya ada di git, dan komponen yang dikompilasi tidak, sama dengan bagaimana distatau outputfolder yang di-gitignored dalam proyek grunt dan tegukan.
Kostia
160

Kekhawatiran terbesar saya dengan tidak memeriksa node_moduleske git adalah bahwa 10 tahun ke depan, ketika aplikasi produksi Anda masih digunakan, npm mungkin tidak ada. Atau npm mungkin rusak; atau pengelola mungkin memutuskan untuk menghapus perpustakaan yang Anda andalkan dari repositori mereka; atau versi yang Anda gunakan mungkin dipangkas.

Ini dapat dikurangi dengan manajer repo seperti pakar, karena Anda selalu dapat menggunakan Nexus atau Artifactory lokal Anda sendiri untuk memelihara mirror dengan paket yang Anda gunakan. Sejauh yang saya mengerti, sistem seperti itu tidak ada untuk npm. Hal yang sama berlaku untuk manajer perpustakaan sisi klien seperti Bower dan Jamjs.

Jika Anda telah mengkomit file ke git repo Anda sendiri, maka Anda dapat memperbaruinya sesuka Anda, dan Anda memiliki kenyamanan build berulang dan pengetahuan bahwa aplikasi Anda tidak akan rusak karena beberapa tindakan pihak ketiga.

Jonathan
sumber
10
Banyak pilihan hari ini: Nexus ( issues.sonatype.org/browse/NEXUS-5852 ), Artifactory ( jfrog.com/jira/browse/RTFACT-5143 ), npm_lazy ( github.com/mixu/npm_lazy ), npm-lazy- mirror ( npmjs.org/package/npm-lazy-mirror ), dll.
Johann
4
Kutipan dari npmjs FAQ: "Jika Anda paranoid tentang bergantung pada ekosistem npm, Anda harus menjalankan mirror npm pribadi atau cache pribadi.". Saya pikir ini menunjuk pada masalah yang Anda maksudkan, bukan?
Taylan
2
Npm tidak akan hilang dalam semalam, jadi manfaatnya tidak benar-benar berpasangan dengan hilangnya kejelasan dalam sejarah komit Anda dan ukuran bundel besar Anda. Jika seseorang membangun aplikasi yang menurut mereka masih akan aktif dalam 10 tahun, masuk akal untuk berharap bahwa itu akan menerima banyak perawatan di sepanjang jalan. Poin tentang pemadaman NPM adalah argumen yang jauh lebih baik, meskipun mungkin ada cara yang lebih baik untuk mengurangi risiko itu daripada berkomitmen untuk sumber.
Sam P
3
Bahkan satu bulan kemudian berbahaya jika Anda tidak melakukan dependensi Anda (lebih disukai di repositori terpisah). Ketika saya menemukan suatu pagi ketika saya mengkloning salah satu proyek saya dan menemukan versi paket telah dihapus dari npm. Saya menghabiskan setengah hari untuk mengubah semua versi saya dari cascading dependency untuk mendapatkan pembaruan npm agar berfungsi dan dibangun kembali.
Richard
67

Anda tidak harus memasukkannode_modules dalam .gitignore(atau lebih tepatnya Anda harus memasukkan node_modules dalam sumber Anda digunakan untuk Heroku).

Jika node_modules:

  • ada kemudian npm installakan menggunakan lib yang dibatalkan tersebut dan akan membangun kembali dependensi biner dengan npm rebuild.
  • tidak ada maka npm installharus mengambil semua dependensi itu sendiri yang menambah waktu untuk langkah kompilasi siput.

Lihat sumber buildpack Node.js untuk langkah-langkah yang tepat ini

Namun, kesalahan awal tampaknya menjadi ketidakcocokan antara versi npmdan node. Adalah ide yang baik untuk selalu secara eksplisit mengatur enginesbagian Anda packages.jsonsesuai dengan panduan ini untuk menghindari situasi seperti ini:

{
  "name": "myapp",
  "version": "0.0.1",
  "engines": {
    "node": "0.8.x",
    "npm":  "1.1.x"
  }
}

Ini akan memastikan paritas dev / prod dan mengurangi kemungkinan situasi seperti itu di masa depan.

Ryan Daigle
sumber
Terima kasih atas bantuannya Ryan. Itu membuat saya melewati kesalahan versi npm tapi sekarang gagal ketika mengkompilasi paket redis. Pesan kesalahan adalah "OSError: [Errno 2] Tidak ada file atau direktori: '/ Users / Jason / tastemade / tastebase / node_modules / redis-url / node_modules / redis / node_modules / hiredis / build'". Sepertinya menggunakan jalur dari kotak lokal saya di server heroku. Apakah ada file tertentu di node_modules yang perlu saya tambahkan ke .gitignore?
Jason Griffin
Saya tidak yakin apa yang terjadi dengan perpustakaan tertentu itu, tetapi saya akan mencoba mengecualikan node_modules dari git dalam kasus ini dan melihat apakah itu membantu (memaksa npm untuk mengambil semuanya sendiri dan memastikan lingkungan build yang baru).
Ryan Daigle
@RyanDaigle Praktik terbaik sekarang (Nov 2013) yang direkomendasikan oleh npm ( npmjs.org/doc/… ) dan heroku ( devcenter.heroku.com/articles/… ) adalah untuk memeriksa node_modules untuk git. Apakah Anda memperbarui jawaban Anda (karena memiliki penagihan teratas)?
Tim Diggins
Sambil mendorong ke heroku Anda akan mendapatkan output "-----> Caching direktori node_modules untuk build mendatang". Ini untuk mempersingkat kompilasi siput di masa depan.
ph3nx
Saya punya masalah bahwa filepath node_modules terlalu panjang untuk dikomit. Git tidak akan menemukan file.
Kode Firaun
22

Saya akan meninggalkan ini setelah komentar ini: Haruskah saya memeriksa node_modules untuk git saat membuat aplikasi node.js di Heroku?

Tapi stackoverflow memformatnya aneh. Jika Anda tidak memiliki mesin yang identik dan sedang memeriksa di node_modules, lakukan .gitignore pada ekstensi asli. .Gitignore kami terlihat seperti:

# Ignore native extensions in the node_modules folder (things changed by npm rebuild)
node_modules/**/*.node
node_modules/**/*.o
node_modules/**/*.a
node_modules/**/*.mk
node_modules/**/*.gypi
node_modules/**/*.target
node_modules/**/.deps/
node_modules/**/build/Makefile
node_modules/**/**/build/Makefile

Uji ini dengan terlebih dahulu memeriksa semuanya, dan kemudian minta pengembang lain melakukan yang berikut:

rm -rf node_modules
git checkout -- node_modules
npm rebuild
git status

Pastikan tidak ada file yang berubah.

ibash
sumber
Baru saja menambahkan ini. Memecahkan masalah saya. Jendela-jendela github terus macet mencoba untuk mengakses lebih dari 7000 file node_module: /
Batman
10

Saya percaya bahwa npm installseharusnya tidak berjalan di lingkungan produksi. Ada beberapa hal yang bisa salah - pemadaman npm, unduhan dependensi yang lebih baru (shrinkwrap tampaknya menyelesaikan ini) adalah dua di antaranya.

Di sisi lain, node_modulestidak boleh dilakukan pada git. Terlepas dari ukurannya yang besar, komitmen termasuk mereka dapat menjadi hal yang mengganggu.

Solusi terbaik adalah: npm installharus dijalankan dalam lingkungan CI yang mirip dengan lingkungan produksi. Semua tes akan berjalan dan file rilis zip akan dibuat yang akan mencakup semua dependensi.

pengguna2468170
sumber
Mengapa Anda memiliki langkah yang berjalan pada CI yang tidak akan berjalan sebagai bagian dari penerapan Anda? Ini berarti Anda tidak memiliki paritas antara 2 sistem! Sebagai jawabannya mengatakan di atas - komit folder hanya mengabaikan ekstensi asli, dengan cara itu Anda tertutup untuk hal-hal seperti pemadaman NPM
Voycey
1
Terima kasih atas komentar Anda. Saya percaya bahwa node_modules yang berjalan di server produksi Anda harus dihasilkan dari instalasi npm, bukan dari apa pun yang telah dilakukan devs. Folder node_modules dev tidak selalu cocok dengan konten package.json.
user2468170
8

Saya telah menggunakan folder komit simpul_modules dan menyusut-membungkus. Kedua solusi itu tidak membuat saya bahagia.

Singkatnya: commit node_modules menambahkan terlalu banyak noise ke repositori.
Dan shrinkwrap.json tidak mudah dikelola dan tidak ada jaminan bahwa beberapa proyek yang dibungkus susut akan dibangun dalam beberapa tahun.

Saya menemukan bahwa Mozilla menggunakan repositori terpisah untuk salah satu proyek mereka https://github.com/mozilla-b2g/gaia-node-modules

Jadi tidak butuh waktu lama bagi saya untuk mengimplementasikan ide ini dalam alat simpul CLI https://github.com/bestander/npm-git-lock

Tepat sebelum setiap build ditambahkan
npm-git-lock --repo [[email protected]: your / dedicated / node_modules / git / repository.git]

Ini akan menghitung hash dari package.json Anda dan akan memeriksa konten node_modules dari repo jarak jauh, atau, jika ini adalah build pertama untuk package.json ini, akan melakukan pembersihan npm installdan mendorong hasilnya ke repo jarak jauh.

bestander
sumber
5

Apa yang berhasil untuk saya adalah secara eksplisit menambahkan versi npm ke package.json ("npm": "1.1.x") dan TIDAK memeriksa node_modules ke git. Mungkin lebih lambat untuk digunakan (karena mengunduh paket setiap kali), tetapi saya tidak bisa mendapatkan paket untuk dikompilasi ketika mereka check in. Heroku sedang mencari file yang hanya ada di kotak lokal saya.

Jason Griffin
sumber
Jika Anda merasa jawaban saya adalah jawaban yang benar, terimalah? Terima kasih!
Ryan Daigle
Dalam hal ini masih bisa diperdebatkan, saya akan melihat posting stackoverflow ini yang hampir merupakan duplikat dari pertanyaan Anda di atas: stackoverflow.com/questions/11459733/... Pada dasarnya, konvensi ini untuk memeriksa node_modules, dan kelola versi modul-modul Anda secara lokal. Ini tampaknya cukup masuk akal, dan mungkin penjelasan paling ringkas adalah ini: mikealrogers.com/posts/nodemodules-in-git.html Semoga beruntung!
warriorpostman
3

Alih-alih memeriksa di node_modules, buat file package.json untuk aplikasi Anda.

File package.json menentukan dependensi aplikasi Anda. Heroku kemudian dapat memberitahu npm untuk menginstal semua dependensi itu. Tutorial yang Anda tautkan berisi bagian pada file package.json.

matzahboy
sumber
Saya punya package.json. Ini memiliki yang berikut: {"nama": "simpul-contoh", "versi": "0.0.1", "dependensi": {"express": "2.5.x", "redis-url": "0.1. 0 "," mongodb ":"> = 0.9.9 "}," engine ": {" node ":" 0.8.x "}}
Jason Griffin
Saya lakukan pada kotak lokal saya untuk membuat direktori node_modules. Itulah yang saya laporkan, lalu dihapus, lalu ditambahkan kembali.
Jason Griffin
Setelah melihat tutorial lebih lanjut, sepertinya mereka melakukan node_modules. Dalam hal ini, saya tidak yakin apakah ada cara untuk tidak melakukan node_modules. Maaf
matzahboy
3

Saya menggunakan solusi ini:

  1. Buat repositori terpisah yang menampung node_modules. Jika Anda memiliki modul asli yang harus dibuat untuk platform tertentu maka buat repositori terpisah untuk setiap platform.
  2. Lampirkan repositori ini ke repositori proyek Anda dengan git submodule:

git submodule add .../your_project_node_modules_windows.git node_modules_windows

git submodule add .../your_project_node_modules_linux_x86_64 node_modules_linux_x86_64

  1. Buat link dari platform-spesifik node_modulesuntuk node_modulesdirektori dan menambahkan node_moduleske .gitignore.
  2. Lari npm install.
  3. Melakukan perubahan repositori submodule.
  4. Komit perubahan repositori proyek Anda.

Jadi Anda dapat dengan mudah beralih di antara node_modulesplatform yang berbeda (misalnya jika Anda mengembangkan pada OS X dan menggunakan untuk Linux).

mixel
sumber
3

Dari https://web.archive.org/web/20150212165006/http://www.futurealoof.com/posts/nodemodules-in-git.html :

Sunting: Tautan asli adalah yang ini tetapi sekarang sudah mati. Terima kasih @ Flavio untuk menunjukkannya.

Untuk rekap.

  • Hanya checkin node_modules untuk aplikasi yang Anda gunakan, bukan paket yang dapat digunakan kembali yang Anda kelola.
  • Setiap dependensi yang dikompilasi harus memiliki sumbernya diperiksa, bukan target kompilasi, dan $ npm harus dibangun kembali saat digunakan.

Bagian Favorit saya:

Kalian semua yang menambahkan node_modules ke gitignore Anda, hapus omong kosong itu, hari ini , itu adalah artefak dari era yang kita semua terlalu senang untuk tinggalkan. Era modul global sudah mati.

Benjamin Crouzier
sumber
Situs yang Anda tautkan tampaknya telah kedaluwarsa dan sekarang penuh dengan iklan scammy. Saya berharap iklan-iklan itu adalah "artefak era yang kita semua akan dengan senang hati tinggalkan".
Flavio Copes
1
@ FlavioCopes Memperbarui jawaban saya dengan tautan dari Wayback Machine.
Benjamin Crouzier
2

http://nodejs.org/api/modules.html

[...] simpul dimulai pada direktori induk modul saat ini, dan menambahkan /node_modules, dan mencoba memuat modul dari lokasi itu.

Jika tidak ditemukan di sana, maka pindah ke direktori induk, dan seterusnya , sampai akar pohon tercapai.

Jika Anda menggulirkan modul Anda sendiri khusus untuk aplikasi Anda, Anda dapat menyimpannya ( dan hanya itu ) di aplikasi Anda /node_modules. Dan pindahkan semua dependensi lain ke direktori induk.

Ini kasus penggunaan yang cukup luar biasa, memungkinkan Anda menjaga modul yang Anda buat khusus untuk aplikasi Anda dengan baik dengan aplikasi Anda, dan tidak mengacaukan aplikasi Anda dengan dependensi yang dapat diinstal nanti.

laggingreflex
sumber
1

skenario 1:

Satu skenario: Anda menggunakan paket yang dihapus dari npm. Jika Anda memiliki semua modul di folder node_modules, maka itu tidak akan menjadi masalah bagi Anda. Jika Anda hanya memiliki nama paket di package.json, Anda tidak bisa mendapatkannya lagi. Jika suatu paket kurang dari 24 jam, Anda dapat dengan mudah menghapusnya dari npm. Jika lebih dari 24 jam, maka Anda perlu menghubungi mereka. Tapi:

Jika Anda menghubungi dukungan, mereka akan memeriksa untuk melihat apakah menghapus versi paket Anda akan merusak instalasi lain. Jika demikian, kami tidak akan menghapusnya.

Baca lebih banyak

Jadi peluang untuk ini rendah, tetapi ada skenario 2 ...


skenario 2:

Skenario lain di mana ini terjadi: Anda mengembangkan versi perusahaan dari perangkat lunak Anda atau perangkat lunak yang sangat penting dan menulis di paket Anda. Json:

"dependencies": {
    "studpid-package": "~1.0.1"
}

Anda menggunakan metode function1(x)paket itu.

Sekarang para pengembang paket-studpid mengubah nama metode function1(x)menjadi function2(x)dan mereka membuat kesalahan ... Mereka mengubah versi paket mereka dari 1.0.1menjadi 1.1.0. Itu masalah karena ketika Anda menelepon npm installwaktu berikutnya, Anda akan menerima versi 1.1.0karena Anda menggunakan tilde ( "studpid-package": "~1.0.1").

Panggilan function1(x)dapat menyebabkan kesalahan dan masalah sekarang.


Mendorong seluruh folder node_modules (seringkali lebih dari 100 MB) ke repositori Anda, akan menghabiskan ruang memori Anda. Beberapa kb (hanya package.json) dibandingkan dengan ratusan MB (package.json & node_modules) ... Pikirkanlah.

Anda dapat melakukannya / harus memikirkannya jika:

  • perangkat lunaknya sangat penting.

  • Anda dikenakan biaya ketika ada sesuatu yang gagal.

  • Anda tidak mempercayai registri npm. NPM terpusat dan secara teoritis dapat ditutup.

Anda tidak perlu menerbitkan folder node_modules di 99,9% dari kasus jika:

  • Anda mengembangkan perangkat lunak hanya untuk diri Anda sendiri.

  • Anda telah memprogram sesuatu dan hanya ingin mempublikasikan hasilnya di GitHub karena orang lain mungkin tertarik.


Jika Anda tidak ingin node_modules berada di repositori Anda, cukup buat .gitignorefile dan tambahkan baris node_modules.

ndsvw
sumber