2013-03-02 54 views
45

Có cách nào để chỉ định các phụ thuộc cụ thể của OS trong tệp npm package.json không?npm package.json Hệ điều hành phụ thuộc cụ thể

Ví dụ: tôi chỉ muốn cài đặt 'dbus' (https://npmjs.org/package/dbus) làm phụ thuộc cho mô-đun của mình nếu người dùng đang chạy Linux. Tôi sẽ có một sự phụ thuộc khác nhau cho Mac và Windows.

+5

Câu hỏi hay. Tôi biết có trường 'os' trong [package.json] (https://npmjs.org/doc/json.html), nhưng điều đó không cho phép bạn trao đổi các phụ thuộc dựa trên nền tảng hiện tại - nó chỉ khai báo những gói phần mềm được đưa vào danh sách trắng/danh sách cấm trên đó. Ví dụ, tài sản trong 'package.json' này: ' "os": [ "! Win32", "darwin"] ' có nghĩa là "gói này sẽ không chạy trong các cửa sổ nhưng sẽ chạy trên Mac".Thật không may, điều này không thực sự đạt được những gì bạn đang yêu cầu. – smithclay

+0

^Đó chính xác là vấn đề, nếu mô đun dbus có các liên kết gốc sẽ chỉ biên dịch trên một hệ điều hành cụ thể ([như đã đề cập bên dưới trong chú thích] (http://stackoverflow.com/questions/15176082/npm-package-json- os-specific-dependency # comment22801812_15670089)), package.json của nó nên bao gồm trường 'os' đó. –

Trả lời

25

Có cách tốt để thực hiện việc này, tùy thuộc vào thiết lập của bạn.

NPM package.json hỗ trợ một os chủ chốt,

và cũng optionalDependencies

  • os có thể được dùng để xác định hệ điều hành một mô-đun có thể được cài đặt trên.
  • optionalDependencies là phụ thuộc vào mô-đun nếu chúng không thể được cài đặt, npm bỏ qua chúng và tiếp tục cài đặt.

Bằng cách này bạn có thể có mô-đun của bạn có một sự phụ thuộc tùy chọn cho mỗi hệ điều hành, và chỉ có một mà các công trình sẽ được nạp/cài đặt^^

EDIT:. Như @Sebastien đề cập dưới đây, phương pháp này nguy hiểm. Đối với bất kỳ hệ điều hành nào, ít nhất một trong các phụ thuộc của bạn là "bắt buộc" và phần còn lại "tùy chọn". Làm cho tất cả các phiên bản của phụ thuộc tùy chọn có nghĩa là nếu cài đặt của bạn không thành công vì lý do chính đáng, nó sẽ tự động bỏ qua cài đặt và bạn sẽ thiếu một sự phụ thuộc mà bạn thực sự cần.

+2

Chỉ tìm thấy câu trả lời này (sau khi trả lời bình luận của bạn về antipatterns). Điều này trông giống như một giải pháp tốt hơn nhiều so với sử dụng một kịch bản cài đặt! Bây giờ tôi biết điều này có sẵn, bạn có thể bỏ qua bình luận của tôi (tôi sẽ thử và xóa/chỉnh sửa nó nếu nó không quá muộn) – Metalskin

+0

Tôi cũng muốn tôi có thể xóa bình luận của mình, vì tôi đã sử dụng kịch bản cài đặt với giải pháp này>. < – TinyTimZamboni

+0

bạn có thể cho tôi xem một ví dụ hoàn chỉnh không? nói 'fsevents' là phụ thuộc tùy chọn trên OSX mà tôi KHÔNG quan tâm vì kịch bản xây dựng của tôi đang chạy trên LINUX. –

6

Tôi nghĩ câu trả lời ngắn gọn là không. Mặc dù vậy, tôi có thể nghĩ đến một vài cách giải quyết - đơn giản nhất là chỉ thêm mọi thứ vào package.json bất kể hệ điều hành, và sau đó là require() đúng thời gian khi chạy.

Nếu điều đó không làm việc cho bạn, bạn có thể sử dụng một cài đặt kịch bản để có được những kết quả mà bạn đang đi cho - https://docs.npmjs.com/misc/scripts

tôi đã không kiểm tra này, nhưng tôi nghĩ rằng nó sẽ làm việc:

Thêm một cái gì đó như thế này để package.json của bạn:

,"scripts": { 
    "install": "node install_dependencies.js" 
} 

và sau đó thêm một tập tin install_dependencies.js để kiểm tra hệ điều hành và chạy npm install ... lệnh thích hợp.

+5

Vấn đề là phụ thuộc của tôi có ràng buộc bản địa chỉ biên dịch trên một hệ điều hành cụ thể, vì vậy tôi không thể có chúng như là phụ thuộc rõ ràng. Đề xuất của bạn cho tập lệnh npm install hoạt động, tôi đã sử dụng os.platform() để phát hiện nền tảng người dùng đang sử dụng; – sandeepmistry

+2

kịch bản cài đặt hiện được coi là 'antipattern' [source] (https://www.npmjs.org/doc/misc/npm-scripts.html#note-install-scripts-are-an-antipattern). Thay vào đó nên sử dụng tệp biên dịch .gyp – TinyTimZamboni

+1

Chỉ cần một quan sát không rõ ràng đối với tôi ở trên. Nếu sử dụng 'package.json' để quản lý cài đặt cho một dự án và bạn không xuất bản, thì sử dụng .gyp không phải là giải pháp. Tham khảo bài viết dưới đây của TinyTimZamboni, nó phù hợp hơn cho kịch bản này (http://stackoverflow.com/a/26069595/1125784). – Metalskin

1

Ngoài ra còn có các bindings-shyp mô-đun:

https://www.npmjs.com/package/bindings-shyp

mô-đun Helper cho tải tập tin .node mô-đun mẹ đẻ của bạn

Đây là một mô-đun helper cho các tác giả của Node Các module addon gốc .js. Về cơ bản, nó là "con dao quân đội Thụy Sĩ" yêu cầu() nhập tệp .node của mô-đun gốc của bạn.

Trong suốt quá trình bổ trợ gốc của Node, addons đã được biên dịch ở nhiều nơi khác nhau, tùy thuộc vào công cụ xây dựng và phiên bản nút nào được sử dụng. Để làm cho vấn đề tồi tệ hơn, bây giờ công cụ xây dựng gyp có thể tạo ra bản phát hành Bản phát hành hoặc Gỡ lỗi, mỗi bản dựng được xây dựng thành các vị trí khác nhau.

Mô-đun này kiểm tra tất cả các vị trí có thể có một phần bổ trợ gốc sẽ được tạo tại và trả về giá trị đầu tiên tải thành công.

0

Trích dẫn @npm_support tại địa chỉ:

https://twitter.com/npm_support/status/968195526989512705

2/2 Nếu bạn muốn tránh các vấn đề liên quan đến cài đặt phụ thuộc, một tuyến đường là dành cho bạn để viết một wrapper đó là yêu cầu như một phụ thuộc thường xuyên, và để đảm bảo rằng nó có optionalDeps (và cũng đảm bảo rằng trình bao bọc xác minh bạn có mọi thứ cần thiết để làm việc).

Nhưng IMHO nó trông giống như giải pháp thay vì giải quyết vấn đề thực.

Tôi có thể hiểu rằng npm muốn bảo tồn tính di động và tránh xử lý các đặc trưng nền tảng, nhưng nó phải được thực hiện và IMHO thực hiện điều này trong thời gian chạy không phải là tối ưu (đặc biệt nếu ai muốn tối ưu hóa kích thước mã).

Vì vậy, hôm nay tôi không có giải pháp tối ưu để chia sẻ mà là một cuộc thảo luận mở cho đề xuất.

Không thể "hỗ trợ phụ thuộc có điều kiện" trong npm?

Điều đầu tiên mà tôi nghĩ đến là thêm phần "ghi đè" sẽ thay đổi (+ thêm, -remove, = thay thế) các phần được phân tích cú pháp hiện tại.

Ví dụ:

dependencies: { "common-stuff": "*" } overrides: { "os: { linux: { dependencies: { "+best-linux-module" } } } }

Và tùy chọn khác được đề xuất bởi một nhà phát triển tôi biết, sẽ giới thiệu một cung cấp từ khóa, sau đó một số module có thể cung cấp cùng một ngữ nghĩa hơn sẽ được thỏa mãn bởi resolver (a la debian), nhưng nó tạo ra chi phí tương tự.

Tôi đang tìm cách tiếp cận chung không chỉ tập trung vào hỗ trợ hệ điều hành mà còn trên các hương vị khác của gói (tùy thuộc vào công cụ chẳng hạn).

Bạn có biết bất kỳ sự cố liên quan nào trong trình theo dõi NPM không? nếu không tôi đang xem xét để nộp một lỗi để được theo dõi tại địa chỉ:

https://github.com/npm/npm/issues?q=dependencies+conditional

Phản hồi hoan nghênh ý tưởng này.