Menggunakan npm untuk menginstal atau memperbarui paket yang diperlukan seperti bundler untuk rubygems

88

Saya suka Bundler , sangat bagus dalam manajemen ketergantungan. Saya suka npm , menginstal paket node itu mudah! Saya memiliki aplikasi nodejs dan ingin sekali dapat menentukan dependensi aplikasi saya dan menginstal / memperbaruinya dengan mudah di mana pun saya menerapkan aplikasi saya. Ini bukan perpustakaan yang saya rilis, ini adalah aplikasi web lengkap.

Saya mengetahui npm bundleperintahnya, tetapi itu sepertinya hanya menimpa direktori tempat paket diinstal.

Saya terbiasa menggunakan bundler dengan cara ini:

# Gemfile
gem "rails", "3.0.3"

Menginstal rails v3.0.3 dan permata lain yang diperlukan di mesin host hanya jika belum ada

> bundle install

Bagaimana saya bisa mencapai sesuatu yang serupa dengan npm?

Daniel Beardsley
sumber
bukankah jawaban saya yang ingin Anda ketahui?
Alfred

Jawaban:

147

Pada npm 1.0 (yang sekarang Anda dapatkan secara default jika Anda mengikuti langkah-langkah dalam file README), "bundle" tidak lagi menjadi hal yang terpisah - ini hanya "cara kerjanya".

Begitu:

  1. Letakkan package.jsonfile di root proyek Anda
  2. Cantumkan deps Anda di file itu

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
    
  3. npm install Karena Anda memanggil ini tanpa args, dan bukan dalam mode global, itu hanya akan menginstal semua deps Anda secara lokal.

  4. require("express") dan berbahagialah.
isaacs
sumber
2
Saat dalam produksi, saya sangat menyarankan untuk mengubah your_app/node_modulesdirektori lokal menjadi symlink di luar direktori aplikasi Anda. Anda tidak ingin mengunduh, membangun, dan menginstal setiap dependensi setiap kali Anda menerapkan.
Daniel Beardsley
Baik. bagaimana jika saya lupa memperbarui package.json saya? Apakah ada cara untuk memaksa NPM mencari bukan package.json tetapi untuk paket yang saya gunakan dalam kode saya?
Pono
4
Ini tidak sepenuhnya benar. NPM akan menginstal semua dependensi di atas my-projectdi ./node_modules/my-project/node_modules. Saya tidak yakin apakah ada cara yang mudah untuk menginstal semua dependensi di ./node_modules Anyone?
Daniel Beardsley
@DanielBeards Saya tidak berpikir begitulah cara npm bekerja. Jika Anda melihat perilaku itu, dan Anda dapat mereproduksinya, posting masalah di halaman github npm.
isaacs
2
Setuju dengan @DanielBeardsley. Saya menderita perilaku yang bahkan dengan NPM 1.1.70
graffic
10

Sunting: Ini hanya berlaku untuk versi npm <1.0


Cukup sulit untuk memahami hal ini, tetapi NPM memungkinkannya .

Anda membutuhkan tiga komponen

  1. Subdirektori di repositori Anda (yaitu deps/)
  2. Sebuah package.jsonfile dalam direktori di atas bahwa daftar dependensi
  3. Sebuah index.jsfile dalam direktori di atas yang membutuhkan dependensi Anda

Contoh

Bayangkan bahwa ekspres adalah satu-satunya ketergantungan Anda

deps / package.json

catatan: Tingkatkan versi # setiap kali Anda mengubah dependensi

{
  "name": "myapp_dependencies",
  "version": "0.0.1",
  "engines": {
    "node": "0.4.1"
  },
  "dependencies":{
    "express": "2.0.0beta2"
  }
}

deps / index.js

export.modules = {
  express: require('express')
  //add more
}

Sekarang Anda dapat menginstal dependensi Anda menggunakan npm. Anda bahkan dapat menjadikan ini sebagai bagian dari proses penerapan Anda

cd deps
npm install

Kemudian dalam kode aplikasi Anda, Anda bisa mendapatkan akses ke versi ekspres tertentu seperti ini:

var express = require('myapp_dependencies').express;
Daniel Beardsley
sumber
Terima kasih, ini adalah metode terbaik yang pernah saya lihat sejauh ini. Namun, bukankah require('express')in deps / index.js hanya mengimpor versi ekspres terbaru, dan belum tentu versi yang kami instal? Saya seorang noob nodeJS jadi mohon bersabarlah.
adamJLev
Tidak, itulah keajaiban npm install, ia menambahkan symlink di dalam direktori paket yang Anda instal ke versi yang benar dari paket dependen. Jika paket dependensi Anda diperlukan, require('express')pemeriksaan direktori lokal terlebih dahulu dan temukan symlink ke versi express yang benar.
Daniel Beardsley
5

Anda harus membaca dua artikel ini dari blog Isaacs (penulis npm). Saya pikir mereka sangat bagus, dan saya yakin memberi tahu Anda bagaimana mencapai tujuan Anda:

  1. http://blog.izs.me/post/1675072029/10-cool-things-you-probably-didnt-realize-npm-could-do
  2. http://foohack.com/2010/08/intro-to-npm/

Saya percaya tautan # 1 (poin # 11) menjelaskan ini:

11: Gabungkan semua dependensi Anda ke dalam paket itu sendiri

Saat Anda menggunakan perintah npm bundle, npm akan memasukkan semua dependensi Anda ke folder node_modules di paket Anda. Tapi itu tidak berhenti sampai di situ.

Jika Anda ingin bergantung pada sesuatu yang tidak ada di registri, Anda dapat melakukannya. Lakukan saja ini:

npm bundle install http://github.com/whoever/whatever/tarball/master Ini akan menginstal konten tarball itu ke dalam bundel, dan kemudian Anda dapat mencantumkannya sebagai dependensi, dan ia tidak akan mencoba menginstalnya ketika paket Anda terinstal.

Ini juga berguna jika Anda memiliki garpu sendiri untuk sesuatu, dan lebih memilih untuk tidak mengubah namanya.

Nyatanya, Anda dapat menjalankan hampir semua perintah npm di bundel. Untuk melihat isinya, Anda bisa melakukan npm bundle ls. Untuk menghapus sesuatu, lakukan hal npm bundle rm. Dan, tentu saja, Anda dapat menginstal beberapa versi dan mengaktifkan versi yang Anda inginkan.

Alfred
sumber
Ini berguna, meskipun bukan itu yang saya cari. Mungkin saya perlu menambahkan klarifikasi. Saya mencari cara untuk menginstal atau memperbarui secara otomatis (di mesin tujuan) paket NPM yang menjadi tempat bergantung aplikasi saya setiap kali saya menerapkannya. Sepertinya npm bundledigunakan untuk mengumpulkan semua dependensi Anda ke direktori tertentu selain default. Saya mungkin akan menemukan solusi saya sendiri yang kinerjanya mirip dengan bundle install( bundleruntuk ruby)
Daniel Beardsley
1
Sekadar catatan, sejak npmversi 1.0+, npm bundletelah dihapus. Sebagai gantinya, cukup gunakan npm installperintah tanpa nama paket, itu akan membaca package.json dan menarik paket yang diperlukan.
Arthur Maltson
2

Pada Npm versi 1.1.2, ada perintah baru npm shrinkwrapyang membuat npm-shrinkwrapped.jsonfile, mirip dengan Gemfile.lock. Sangat penting untuk membuatnya, untuk mencegah pembusukan perangkat lunak (lihat alasan Bundler ). Terutama karena Nodejs memiliki komunitas yang bergerak cepat.

While bundle installmembuat secara Gemfile.lockotomatis, npm installtidak akan membuat npm-shrinkwrapped.json(tetapi akan menggunakannya jika ada). Karenanya Anda harus ingat untuk menggunakan npm shrinkwrap.

Baca panduan lengkapnya di http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/

Kolonel Panic
sumber
2

Bagi saya, solusi paling sederhana adalah menggunakan package.jsonfile dengan privateflag (ditambahkan ke npm bulan lalu) disetel ke true. Dengan cara itu, Anda dapat menjalankan npm installatau npm bundlemengambil dependensi proyek Anda, tetapi Anda mencegah siapa pun secara tidak sengaja menerbitkan proyek non-publik Anda.

Berikut contohnya package.json:

{
"name": "yourProject"
,"version": "1.0.0"
,"dependencies": { "express" : ">=2.1.0" }
,"private": true
}

Menjalankan npm installakan menginstal expressdi sistem lokal jika belum ada; berjalan npm publishmemberikan kesalahan karena "private": true.

Anda dan tim Anda dapat menggunakan tag versi secara internal untuk melacak perubahan dependensi dari waktu ke waktu — setiap kali Anda mengubah dependensi, ubah versinya. Untuk melihat versi mana yang telah Anda instal, gunakan npm ls installed.

Trevor Burnham
sumber
Saya pikir Anda tidak boleh mengutip truedan itu hanya berfungsi karena string adalah nilai kebenaran (yaitu, !!"false" === true).
Camilo Martin
1

Publikasikan aplikasi Anda npmjuga, dan cantumkan dependensinya di file package.json Anda.

Ketika seseorang menggunakan npmuntuk menginstal paket Anda, npmakan mengurus menyelesaikan dependensinya.

Spesifikasi paket: http://wiki.commonjs.org/wiki/Packages/1.0

Dan Grossman
sumber
Ya, tapi ini adalah aplikasi web non-opensource. Jika Anda memiliki ide yang tidak melibatkan penerbitan aplikasi, harap edit jawaban Anda atau buat yang lain.
Daniel Beardsley
1
Kemudian publikasikan paket seperti "myapp-dependencies" yang dapat digunakan pengguna npmuntuk menginstal sebelum menginstal aplikasi Anda. Saya tidak berpikir ada gempadanan lain untuk node.js.
Dan Grossman