Sử dụng npm để cài đặt hoặc cập nhật các gói yêu cầu giống như gói cho rubygem


88

Tôi yêu Bundler , nó rất tốt trong việc quản lý sự phụ thuộc. Tôi thích npm , cài đặt các gói nút thật dễ dàng! Tôi có một ứng dụng nodejs và rất muốn có thể chỉ định các phần phụ thuộc ứng dụng của mình và dễ dàng cài đặt / cập nhật chúng ở bất cứ nơi nào tôi triển khai ứng dụng của mình. Đây không phải là thư viện mà tôi đang phát hành, mà là một ứng dụng web chính thức.

Tôi biết npm bundlelệnh, nhưng điều đó dường như chỉ đơn giản là ghi đè lên thư mục nơi các gói được cài đặt.

Tôi đã quen với việc sử dụng Bundler theo kiểu này:

# Gemfile
gem "rails", "3.0.3"

Chỉ cài đặt rails v3.0.3 và bất kỳ đá quý bắt buộc nào khác trên máy chủ nếu nó chưa tồn tại

> bundle install

Làm cách nào để đạt được điều gì đó tương tự với npm?


câu trả lời của tôi không phải là những gì bạn muốn biết?
Alfred

Câu trả lời:


147

Kể từ npm 1.0 (bây giờ là những gì bạn nhận được theo mặc định nếu bạn làm theo các bước trong tệp README), "gói" không còn là một thứ riêng biệt nữa - nó chỉ là "cách nó hoạt động".

Vì thế:

  1. Đặt một package.jsontệp vào thư mục gốc của dự án của bạn
  2. Liệt kê các nhiệm vụ của bạn trong tệp đó

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
  3. npm install Vì bạn đang gọi điều này mà không có args và không ở chế độ toàn cầu, nó sẽ chỉ cài đặt tất cả các deps của bạn cục bộ.

  4. require("express") và hạnh phúc.

2
Khi đang trong quá trình sản xuất, tôi thực sự khuyên bạn nên thay đổi your_app/node_modulesthư mục cục bộ thành một liên kết tượng trưng bên ngoài thư mục ứng dụng của bạn. Bạn không muốn phải tải xuống, xây dựng và cài đặt từng phần phụ thuộc mỗi khi triển khai.
Daniel Beardsley

Đồng ý. điều gì sẽ xảy ra nếu tôi quên cập nhật package.json của mình? Có cách nào để buộc NPM không tìm kiếm package.json mà đối với các gói tôi đang sử dụng trong mã của mình không?
Pono

4
Điều này không hoàn toàn chính xác. NPM sẽ cài đặt tất cả các phụ thuộc cho phần trên my-projecttrong ./node_modules/my-project/node_modules. Tôi không chắc liệu có cách nào thuận tiện để cài đặt tất cả các phụ thuộc trong ./node_modules Bất kỳ ai không?
Daniel Beardsley

@DanielBeardsley Tôi không nghĩ đó là cách npm hoạt động. Nếu bạn thấy hành vi đó và bạn có thể tái tạo nó, vui lòng đăng vấn đề trên trang github npm.
isaacs

2
Đồng ý với @DanielBeardsley. Tôi bị hành vi đó ngay cả khi npm 1.1.70
graffic

10

Chỉnh sửa: Điều này chỉ áp dụng cho các phiên bản npm <1.0


Khá khó để tìm ra điều này, nhưng NPM đã biến điều này thành khả thi .

Bạn cần ba thành phần

  1. Một thư mục con trong kho lưu trữ của bạn (tức là deps/ )
  2. A package.json tệp trong thư mục trên liệt kê các phần phụ thuộc
  3. Một index.jstệp trong thư mục trên yêu cầu tệp phụ thuộc của bạn

Thí dụ

Hãy tưởng tượng rằng thể hiện là sự phụ thuộc duy nhất của bạn

deps / package.json

lưu ý: Tăng phiên bản # mỗi khi bạn sửa đổi các phụ thuộc

{
  "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
}

Bây giờ bạn sẽ có thể cài đặt các phụ thuộc của mình bằng npm. Bạn thậm chí có thể thực hiện điều này trong quá trình triển khai của mình

cd deps
npm install

Sau đó, trong mã ứng dụng của bạn, bạn có thể có quyền truy cập vào phiên bản express cụ thể của mình như sau:

var express = require('myapp_dependencies').express;

Cảm ơn, đây là phương pháp tốt nhất mà tôi đã thấy cho đến nay. Tuy nhiên, không phải require('express')trong deps / index.js chỉ nhập phiên bản express mới nhất và không nhất thiết là phiên bản chúng tôi đã cài đặt? Tôi là một NodeJS noob nên hãy chịu khó với tôi.
adamJLev

Không, đó là điều kỳ diệu npm install, nó thêm các liên kết tượng trưng trong thư mục của gói đã cài đặt của bạn vào các phiên bản chính xác của các gói phụ thuộc. Khi gói phụ thuộc của bạn được yêu cầu, trước tiên chương trình sẽ require('express')kiểm tra thư mục cục bộ và tìm liên kết tượng trưng cho đúng phiên bản express.
Daniel Beardsley

5

Bạn nên đọc hai bài báo này từ blog của Isaacs (tác giả npm). Tôi nghĩ rằng chúng thực sự tốt và tôi tin rằng sẽ cho bạn biết cách đạt được mục tiêu của mình:

  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/

Tôi tin rằng liên kết số 1 (điểm # 11) giải thích điều này:

11: Gói tất cả các phụ thuộc của bạn vào chính gói

Khi bạn sử dụng lệnh gói npm, npm sẽ đặt tất cả các phần phụ thuộc của bạn vào thư mục node_modules trong gói của bạn. Nhưng nó không dừng lại ở đó.

Nếu bạn muốn phụ thuộc vào thứ gì đó không có trong sổ đăng ký, bạn có thể làm điều đó. Chỉ cần làm điều này:

npm pack install http://github.com/whoever/w Anything/ tarball/ master Thao tác này sẽ cài đặt nội dung của tarball đó vào gói, sau đó bạn có thể liệt kê nó như một phụ thuộc và nó sẽ không cố cài đặt nó khi gói của bạn đã được cài đặt.

Điều này cũng rất hữu ích nếu bạn có một thứ gì đó của riêng mình và không muốn thay đổi tên.

Trên thực tế, bạn có thể chạy hầu hết mọi lệnh npm tại gói. Để xem những gì bên trong, bạn có thể làm npm bó ls. Để loại bỏ một cái gì đó, hãy làm npm nhóm rm thứ. Và, tất nhiên, bạn có thể cài đặt nhiều phiên bản và kích hoạt phiên bản bạn muốn.


Điều này rất hữu ích, mặc dù nó không phải là thứ tôi đang tìm kiếm. Có lẽ tôi cần phải làm rõ thêm. Tôi đang tìm cách tự động cài đặt hoặc cập nhật (trên máy đích) gói NPM mà ứng dụng của tôi phụ thuộc vào bất cứ khi nào tôi triển khai. Nó có vẻ như npm bundleđược sử dụng để thu thập tất cả các phụ thuộc của bạn vào một thư mục cụ thể khác với thư mục mặc định. Tôi có lẽ sẽ đưa ra giải pháp của riêng tôi mà thực hiện tương tự như bundle install( bundlercho ruby)
Daniel Beardsley

1
Chỉ cần lưu ý, kể từ npmphiên bản 1.0+, npm bundleđã bị xóa. Thay vào đó, chỉ cần sử dụng npm installlệnh không có tên gói, nó sẽ đọc package.json và kéo xuống các gói cần thiết.
Arthur Maltson

2

Kể từ phiên bản Npm 1.1.2, có một lệnh mới npm shrinkwraptạo một npm-shrinkwrapped.jsontệp, tương tự như Gemfile.lock. Điều quan trọng là phải tạo một cái để ngăn chặn sự thối rữa của phần mềm (xem cơ sở lý luận của Bundler ). Đặc biệt như Nodejs có một cộng đồng phát triển nhanh như vậy.

Trong khi bundle installtạo một Gemfile.locktự động, npm installsẽ không tạo npm-shrinkwrapped.json(nhưng sẽ sử dụng nó khi nó tồn tại). Do đó bạn cần nhớ để sử dụng npm shrinkwrap.

Đọc hướng dẫn đầy đủ tại http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/


2

Đối với tôi, dường như giải pháp đơn giản nhất là sử dụng một package.jsontệp có privatecờ (được thêm vào npm chỉ vào tháng trước) được đặt thành true. Bằng cách đó, bạn có thể chạy npm installhoặcnpm bundle lấy các phụ thuộc của dự án, nhưng bạn ngăn không cho bất kỳ ai vô tình xuất bản dự án không công khai của bạn.

Đây là một ví dụ package.json:

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

Chạy npm installsẽ cài đặt expresstrên hệ thống cục bộ nếu nó chưa tồn tại; đang chạy npm publishgặp lỗi vì"private": true .

Bạn và nhóm của mình có thể sử dụng thẻ phiên bản trong nội bộ để theo dõi các thay đổi về phụ thuộc theo thời gian — mỗi khi bạn thay đổi phụ thuộc, hãy tăng cường phiên bản. Để xem bạn đã cài đặt phiên bản nào, hãy sử dụng npm ls installed.


Tôi nghĩ rằng bạn không nên trích dẫn truevà nó chỉ hoạt động bởi vì các chuỗi là các giá trị trung thực (nghĩa là !!"false" === true).
Camilo Martin

1

Xuất bản ứng dụng của bạn npmcũng như liệt kê các phụ thuộc của nó trong tệp package.json của bạn.

Khi ai đó sử dụng npmđể cài đặt gói của bạn,npm sẽ giải quyết các phần phụ thuộc của nó.

Thông số gói: http://wiki.commonjs.org/wiki/Packages/1.0


Vâng, nhưng đây là một ứng dụng web không phải nguồn mở. Nếu bạn có ý tưởng không liên quan đến việc xuất bản ứng dụng, vui lòng chỉnh sửa câu trả lời của bạn hoặc tạo một ý tưởng khác.
Daniel Beardsley

1
Sau đó, xuất bản một gói như "myapp-dependencies" mà người dùng của bạn có thể sử dụng npmđể cài đặt trước khi cài đặt ứng dụng của bạn. Tôi không nghĩ có bất kỳ gemtương đương nào khác cho node.js.
Dan Grossman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.