Hashbang yang sesuai untuk skrip Node.js

95

Saya mencoba membuat skrip untuk node.js yang akan berfungsi di berbagai lingkungan. Khususnya bagi saya, saya beralih antara OS X dan Ubuntu. Di versi sebelumnya, Node diinstal sebagai node, tetapi di versi terakhir ini diinstal nodejs. Di bagian atas skrip saya, saya dapat memiliki:

#!/usr/bin/env node

atau

#!/usr/bin/env nodejs

Saya lebih suka skrip dijalankan sebagai yang dapat dieksekusi untuk lingkungan mana pun selama node diinstal daripada memiliki satu atau yang lain harus menentukan perintah ( ./script-name.jsvs. node script-name.js).

Apakah ada cara untuk menentukan hashbang cadangan atau yang kompatibel dalam kedua kasus untuk node.js?

Pil Ledakan
sumber
Anda dapat membuat skrip shell pembungkus untuk memanggil skrip Anda, yang mencoba mencari tahu di mana node tinggal dan apa namanya.
Doon
4
Banyak saran dalam jawaban ini di situs Unix - unix.stackexchange.com/questions/65235/…
sargant
Saya memiliki skrip nodejs yang saya ubah #!/usr/bin/nodemenjadi #!/usr/bin/nodejsketika saya memutakhirkan dari Ubuntu 12.04 ke 12.10. Dan itu dipanggil dari pembungkus yang memeriksa keduanya. Untuk diskusi tentang #!/usr/bin/envperetasan, lihat pertanyaan ini dan jawaban saya .
Keith Thompson
1
Ada proposal TC39 di Tahap 3 yang disebut "Tata Bahasa Hashbang" yang bertujuan untuk standarisasi hashbang yang digunakan: github.com/tc39/proposal-hashbang
M. Twarog

Jawaban:

151

Jika skrip Anda ditujukan untuk digunakan oleh pengembang Node, Anda harus benar-benar menggunakan

#!/usr/bin/env node

dan tidak perlu repot-repot mencoba kompatibilitas dengan orang yang hanya menginstal Node sebagai nodejs.

Alasan:

  • Itulah yang dilakukan anak-anak keren, dan jika Anda tidak melakukannya juga, Anda tidak keren. Proyek simpul besar seperti jshint , karma , pondok , dan bahkan NPM hanya menggunakan #!/usr/bin/env nodesebagai shebang untuk script executable mereka.
  • Karena anak-anak keren melakukannya, siapa pun yang bekerja dengan Node di Ubuntu telah menyiapkan /usr/bin/nodesebagai symlink ke nodejs. Ada instruksi yang sangat dilihat untuk melakukan ini di sini di Stack Overflow, dan di seluruh web. Bahkan ada nodejs-legacypaket yang tujuan utamanya adalah membuat symlink ini untuk Anda. Orang yang menggunakan Node tahu cara memperbaiki masalah ini di Ubuntu, dan mereka harus melakukannya jika ingin menggunakan hampir semua perangkat lunak yang pernah ditulis di Node.
  • Masalahnya bahkan tampaknya tidak ada lagi di Ubuntu 14.04; Saya baru saja membersihkan Node dan menjalankannya apt-get install nodejsdan itu dibuat /usr/bin/nodesebagai symlink ke /etc/alternatives/node. Orang-orang yang terkena masalah ini, saya duga, adalah minoritas yang menyusut.

Meskipun Anda menargetkan orang-orang yang buta huruf Node, Anda mungkin masih ingin menggunakan #!/usr/bin/env node, mungkin menambahkan kemungkinan kebutuhan untuk pembuatan symlink manual atau instalasi nodejs-legacypaket ke dokumentasi instalasi Anda jika Anda menganggapnya perlu. Perhatikan bahwa jika seseorang dengan nodejstetapi tidak nodetersedia mencoba menjalankan program Anda dengan shebang di atas, mereka akan melihat:

/ usr / bin / env: node: File atau direktori tidak ada

dan Googling yang akan memberi mereka perbaikan di hasil pertama dan berkali-kali di halaman pertama.

Jika Anda benar-benar, sangat ingin memastikan bahwa pengguna dapat menjalankan perangkat lunak Anda pada sistem nodejsyang tersedia tetapi nodetidak tersedia (atau di mana nodesebenarnya ada program Node Radio Paket Amatir ), maka Anda dapat menggunakan "shebang dua baris" yang diambil dari Unix & Linux Stack Exchange :

#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"

console.log('Hello world!');

tetapi apakah Anda benar-benar perlu melakukan ini ketika hampir tidak ada orang lain di dunia Node?

Mark Amery
sumber
2
Jika dukungan untuk nodejseksekusi lebih disukai, Anda mungkin merasa sedikit lebih cantik menggunakan shebang dengan #!/bin/shdan //bin/false || exec "$(command -v nodejs || command -v node)" "$0".
lennartcl
2
Perhatikan bahwa Anda tidak dapat meneruskan argumen ke node di Linux , seperti --experimental-modules, jika Anda menggunakan envbaris shebang ini . Ada peretasan, tapi itu jelek .
Dan Dascalescu