Bagaimana cara memeriksa apakah skrip berjalan di bawah Node.js?

159

Saya memiliki skrip yang saya perlukan dari skrip Node.js, yang ingin saya jaga agar mesin JavaScript tetap independen.

Misalnya, saya hanya ingin melakukannya exports.x = y;jika berjalan di bawah Node.js. Bagaimana saya bisa melakukan tes ini?


Ketika memposting pertanyaan ini, saya tidak tahu fitur modul Node.js didasarkan pada CommonJS .

Untuk contoh spesifik yang saya berikan, pertanyaan yang lebih akurat adalah:

Bagaimana sebuah skrip dapat mengetahui apakah skrip tersebut diperlukan sebagai modul CommonJS?

theosp
sumber
3
Saya tidak tahu mengapa Anda mencoba melakukan ini, tetapi sebagai aturan praktis Anda harus menggunakan deteksi fitur daripada deteksi mesin. quirksmode.org/js/support.html
Quentin
4
Ini sebenarnya adalah permintaan tentang bagaimana menerapkan deteksi fitur, tetapi pertanyaannya kurang menggambarkan dirinya.
monokrom
menerbitkan perpustakaan untuk saya gunakan sendiri, bantu ini akan membantu npmjs.com/package/detect-is-node
abhirathore2006
Satu masalah dengan pertanyaan, dan sebagian besar jawabannya, adalah asumsi bahwa hanya ada dua kemungkinan: Browser atau Node.js. Ada kemungkinan bahwa itu bukan browser atau Node.js, seperti halnya dengan Oracle Java Nashorn. Jika JDK diinstal, perintah jjs memungkinkan Anda menjalankan skrip. Tetapi ada banyak perbedaan antara Nashorn dan Node.js sehingga Anda tidak dapat membuat asumsi apa pun. Dan siapa yang tahu opsi apa yang akan datang di masa depan? Deteksi fitur diperlukan.

Jawaban:

80

Dengan mencari dukungan CommonJS , inilah yang dilakukan oleh perpustakaan Underscore.js :

Edit: ke pertanyaan Anda yang diperbarui:

(function () {

    // Establish the root object, `window` in the browser, or `global` on the server.
    var root = this; 

    // Create a reference to this
    var _ = new Object();

    var isNode = false;

    // Export the Underscore object for **CommonJS**, with backwards-compatibility
    // for the old `require()` API. If we're not in CommonJS, add `_` to the
    // global object.
    if (typeof module !== 'undefined' && module.exports) {
            module.exports = _;
            root._ = _;
            isNode = true;
    } else {
            root._ = _;
    }
})();

Contoh di sini mempertahankan pola Modul.

Ross
sumber
45
Ini mendeteksi dukungan CommonJS, yang mungkin didukung browser.
mikemaccana
7
Ada masalah di sini dan nailer "dipaku". Saya mencoba CommonJS di browser, dan pemuat modul yang saya gunakan mendefinisikan module.exports, jadi solusi ini akan salah memberitahu saya bahwa saya berada di simpul.
Mark Melville
1
@MarkMelville bisa dibilang, ini adalah persis apa yang diminta OP jadi karena itu bukan masalah .
Ross
13
Kata-kata buruk di pihak saya. Maksud saya ada masalah dengan solusi ini. OP mungkin telah menerimanya, tetapi saya tidak menerimanya.
Mark Melville
7
Ini pasti BUKAN jawaban terbaik yang diberikan.
user3751385
107

Yah tidak ada cara yang dapat diandalkan untuk mendeteksi berjalan di Node.js karena setiap situs web dapat dengan mudah mendeklarasikan variabel yang sama, namun, karena tidak ada windowobjek di Node.js secara default Anda dapat pergi sebaliknya dan memeriksa apakah Anda menjalankan di dalam Browser.

Ini yang saya gunakan untuk libs yang seharusnya berfungsi baik di Browser dan di bawah Node.js:

if (typeof window === 'undefined') {
    exports.foo = {};

} else {
    window.foo = {};
}

Itu mungkin masih meledak dalam kasus yang windowdidefinisikan di Node.js tetapi tidak ada alasan yang baik untuk seseorang melakukan ini, karena Anda secara eksplisit perlu meninggalkan varatau mengatur properti pada globalobjek.

EDIT

Untuk mendeteksi apakah skrip Anda diperlukan sebagai modul CommonJS, sekali lagi itu tidak mudah. Satu-satunya hal yang umum ditentukanJS adalah bahwa A: Modul akan dimasukkan melalui panggilan ke fungsi requiredan B: Modul mengekspor barang melalui properti pada exportsobjek. Sekarang bagaimana itu diterapkan diserahkan kepada sistem yang mendasarinya. Node.js membungkus konten modul dalam fungsi anonim:

function (exports, require, module, __filename, __dirname) { 

Lihat: https://github.com/ry/node/blob/master/src/node.js#L325

Tapi jangan coba mendeteksi itu melalui beberapa arguments.callee.toString()hal gila , alih-alih gunakan saja kode contoh saya di atas yang memeriksa Browser. Node.js adalah lingkungan yang lebih bersih sehingga tidak mungkin windowdinyatakan di sana.

Ivo Wetzel
sumber
2
Tentang "Node.js adalah lingkungan yang lebih bersih sehingga tidak mungkin jendela akan dideklarasikan di sana.": Well, saya hanya datang ke sini mencari cara untuk mengetahui apakah skrip saya berjalan di peramban yang ditiru oleh node.js + JSDOM atau di peramban biasa ... Alasannya adalah saya memiliki perulangan tak terbatas menggunakan setTimeout untuk memeriksa lokasi URL, yang baik-baik saja di peramban, tetapi membuat skrip node.js berjalan selamanya ... Jadi mungkin ada jendela dalam skrip node.js setelah semua :)
Eric Bréchemier
1
@ Eric Saya sangat meragukannya akan ada di lingkup global, jadi kecuali Anda mengimpor sesuatu seperti windowpada baris pertama modul Anda, Anda seharusnya tidak memiliki masalah. Anda juga bisa menjalankan fungsi anonim dan memeriksa [[Class]]dari thisdalamnya (hanya bekerja dalam modus non-ketat) Lihat "Kelas" di bawah: bonsaiden.github.com/JavaScript-Garden/#typeof
Ivo Wetzel
1
Masalah saya sedikit berbeda dari OP: Saya tidak memerlukan skrip, itu dimuat oleh JSDOM dengan jendela yang ditiru sebagai konteks global ... Masih dijalankan oleh node.js + V8, hanya dalam konteks yang berbeda dari modul biasa.
Eric Bréchemier
1
Mungkin ... Saya pergi ke arah lain: 1) mendeteksi dukungan untuk onhashchange ("onhashchange" di jendela) untuk menghindari membuat loop tak terbatas 2) mensimulasikan dukungan dengan mengatur properti onhashchange pada jendela yang diemulasi pada skrip node.js utama.
Eric Bréchemier
1
typeof self === 'object'mungkin lebih aman karena typeof window === 'undefined'gagal pada lingkup pekerja web.
Lewis
45

Saat ini saya menemukan kesalahan deteksi Node yang tidak mengetahui Node-environment di Electron karena pendeteksian fitur yang menyesatkan. Solusi berikut mengidentifikasi lingkungan proses secara eksplisit.


Identifikasi hanya Node.js

(typeof process !== 'undefined') && (process.release.name === 'node')

Ini akan menemukan jika Anda menjalankan dalam proses Node, karena process.releaseberisi "metadata yang terkait dengan rilis [Node-] saat ini".

Setelah menelurkan io.js nilai process.release.namemungkin juga menjadi io.js(lihat proses-doc ). Untuk mendeteksi lingkungan yang siap-Node dengan benar saya kira Anda harus memeriksa sebagai berikut:

Identifikasi Node (> = 3.0.0) atau io.js

(typeof process !== 'undefined') &&
(process.release.name.search(/node|io.js/) !== -1)

Pernyataan ini diuji dengan Node 5.5.0, Electron 0.36.9 (dengan Node 5.1.1) dan Chrome 48.0.2564.116.

Identifikasi Node (> = 0.10.0) atau io.js

(typeof process !== 'undefined') &&
(typeof process.versions.node !== 'undefined')

Komentar @ daluege mengilhami saya untuk memikirkan bukti yang lebih umum. Ini seharusnya bekerja dari Node.js> = 0.10 . Saya tidak menemukan pengidentifikasi unik untuk versi sebelumnya.


P: Saya memposting jawaban itu di sini karena pertanyaannya mengarahkan saya ke sini, meskipun OP sedang mencari jawaban untuk pertanyaan yang berbeda.

Florian Breisch
sumber
2
Ini tampaknya pendekatan yang paling dapat diandalkan, terima kasih. Padahal hanya berfungsi untuk versi> = 3.0.0.
filip
@daluege - terima kasih atas ilhamnya. Sayangnya saya tidak menemukan bukti lebih rendah dari 0,10.
Florian Breisch
3
Saya menemukan menggunakan webpack reaksi, processdan process.versionada di dalam bundel, jadi saya menambahkan pemeriksaan tambahan untuk process.versiontempat process.release.nodeyang tidak ditentukan pada sisi klien tetapi memiliki versi simpul sebagai nilai pada sisi server
Aaron
@ Harun: terima kasih atas petunjuk itu. Saya tidak dapat menemukan definisi process.versionvariabel (dalam reaksi, webpack, atau react-webpack). Saya akan menghargai setiap petunjuk di mana variabel versi didefinisikan untuk menambahkannya ke jawabannya. Bergantung pada batasan release.node ke simpul> = 3.xx
Florian Breisch
2
Satu-liner dan lebih aman:function isNodejs() { return typeof "process" !== "undefined" && process && process.versions && process.versions.node; }
brillout
25

Masalah dengan mencoba mencari tahu di lingkungan mana kode Anda berjalan adalah bahwa objek apa pun dapat dimodifikasi dan dideklarasikan sehingga hampir mustahil untuk mengetahui objek mana yang asli dari lingkungan, dan yang telah dimodifikasi oleh program.

Namun, ada beberapa trik yang dapat kita gunakan untuk mencari tahu dengan pasti di lingkungan mana Anda berada.

Mari kita mulai dengan solusi yang diterima secara umum yang digunakan di perpustakaan garis bawah:

typeof module !== 'undefined' && module.exports

Teknik ini sebenarnya sangat baik untuk sisi server, seperti ketika requirefungsi dipanggil, itu me-reset thisobjek ke objek kosong, dan mendefinisikan kembali moduleuntuk Anda lagi, yang berarti Anda tidak perlu khawatir tentang gangguan luar. Selama kode Anda dimuat require, Anda aman.

Namun, ini berantakan di browser, karena siapa pun dapat dengan mudah menentukan moduleuntuk membuatnya tampak seperti objek yang Anda cari. Di satu sisi ini mungkin perilaku yang Anda inginkan, tetapi juga menentukan variabel apa yang pengguna perpustakaan dapat gunakan dalam lingkup global. Mungkin seseorang ingin menggunakan variabel dengan nama moduleyang ada exportsdi dalamnya untuk penggunaan lain. Itu tidak mungkin, tetapi siapa kita untuk menilai variabel apa yang bisa digunakan orang lain, hanya karena lingkungan lain menggunakan nama variabel itu?

Kuncinya adalah, jika kita mengasumsikan bahwa skrip Anda sedang dimuat dalam lingkup global (yang akan menjadi itu jika dimuat melalui tag skrip) variabel tidak dapat dicadangkan dalam penutupan luar, karena browser tidak mengizinkan itu . Sekarang ingat dalam simpul, thisobjek adalah objek kosong, namun modulevariabel masih tersedia. Itu karena itu dinyatakan dalam penutupan luar. Jadi kita dapat memperbaiki cek garis bawah dengan menambahkan cek tambahan:

this.module !== module

Dengan ini, jika seseorang menyatakan moduledalam lingkup global di browser, itu akan ditempatkan di thisobjek, yang akan menyebabkan tes gagal, karena this.module, akan menjadi objek yang sama dengan modul. Pada simpul, this.moduletidak ada, dan moduleada dalam penutupan luar, sehingga tes akan berhasil, karena mereka tidak setara.

Dengan demikian, tes terakhir adalah:

typeof module !== 'undefined' && this.module !== module

Catatan: Meskipun ini sekarang memungkinkan modulevariabel untuk digunakan secara bebas di lingkup global, masih dimungkinkan untuk memotong ini di browser dengan membuat penutupan baru dan menyatakan di moduledalamnya, kemudian memuat skrip dalam penutupan itu. Pada saat itu pengguna sepenuhnya mereplikasi lingkungan simpul dan mudah-mudahan tahu apa yang mereka lakukan dan sedang mencoba melakukan gaya simpul yang diperlukan. Jika kode ini disebut dalam tag skrip, kode itu masih aman dari penutupan luar baru.

Waktu
sumber
2
Wow, terima kasih sudah menjelaskan alasannya secara jelas di balik setiap bagian dari one-liner Anda.
Jon Coombs
dapatkan Cannot read property 'module' of undefinedkarena ini tidak terdefinisi dalam tes moka misalnya
srghma
20

Berikut ini berfungsi di browser kecuali secara sengaja, disabotase secara eksplisit:

if(typeof process === 'object' && process + '' === '[object process]'){
    // is node
}
else{
    // not node
}

Bam.

pengguna3751385
sumber
4
var process = {toString: function () {return '[object process]'; }};
Nick Desaulniers
1
Apakah ada beberapa alasan mengapa Anda menggunakan process+''bukan process.toString()?
berbahaya
3
Hampir. Gunakan ini sebagai gantinya:Object.prototype.toString.call(process)
sospedra
2
Ini adalah jawaban terbaik untuk pertanyaan ini.
loretoparisi
3
@armic: var process = null;akan menyebabkan kasus kedua gagal. Dalam Javascript dan Java, ekspresi '' + xmenghasilkan sama seperti x.toString()kecuali ketika xjahat, yang pertama menghasilkan "null"atau di "undefined"mana yang terakhir akan menimbulkan kesalahan.
joeytwiddle
17

Berikut ini cara yang cukup keren untuk melakukannya:

const isBrowser = this.window === this;

Ini berfungsi karena di browser, variabel global 'ini' memiliki referensi sendiri yang disebut 'jendela'. Referensi mandiri ini tidak ada di Node.

  • Di browser 'ini' adalah referensi ke objek global, yang disebut 'jendela'.
  • Dalam Node 'ini' adalah referensi ke objek module.exports.
    • 'ini' bukan referensi ke objek global Node, yang disebut 'global'.
    • 'ini' bukan referensi ke ruang deklarasi variabel modul.

Untuk memutus peramban yang disarankan di atas, Anda harus melakukan sesuatu seperti yang berikut ini

this.window = this;

sebelum melakukan pemeriksaan.

Patrick
sumber
Kenapa tidak sederhana saja const isBrowser = this.window !== undefined? Dan secara teori dalam simpul saya bisa lakukan this.window = thisuntuk menipu solusi.
Tyler Long
11

Deteksi lingkungan lainnya :

(Artinya: sebagian besar jawaban di sini baik-baik saja.)

function isNode() {
    return typeof global === 'object'
        && String(global) === '[object global]'
        && typeof process === 'object'
        && String(process) === '[object process]'
        && global === global.GLOBAL // circular ref
        // process.release.name cannot be altered, unlike process.title
        && /node|io\.js/.test(process.release.name)
        && typeof setImmediate === 'function'
        && setImmediate.length === 4
        && typeof __dirname === 'string'
        && Should I go on ?..
}

Agak paranoid bukan? Anda dapat membuat ini lebih bertele-tele dengan memeriksa lebih banyak global .

Tapi JANGAN !.

Semua ini di atas dapat dipalsukan / disimulasikan.

Misalnya memalsukan globalobjek:

global = {
    toString: function () {
        return '[object global]';
    },
    GLOBAL: global,
    setImmediate: function (a, b, c, d) {}
 };
 setImmediate = function (a, b, c, d) {};
 ...

Ini tidak akan dilampirkan ke objek global asli Node tetapi akan dilampirkan ke windowobjek di browser. Jadi itu akan menyiratkan bahwa Anda berada di Node env di dalam browser.

Hidup ini singkat!

Apakah kita peduli jika lingkungan kita dipalsukan? Itu akan terjadi ketika beberapa pengembang bodoh mendeklarasikan variabel global yang disebut globaldalam lingkup global. Atau beberapa dev jahat menyuntikkan kode ke dalam env kami entah bagaimana.

Kami dapat mencegah kode kami dari mengeksekusi ketika kami menangkap ini, tetapi banyak dependensi lain dari aplikasi kami mungkin terjebak dalam hal ini. Jadi akhirnya kode akan rusak. Jika kode Anda cukup baik, Anda seharusnya tidak mempedulikan masing-masing dan setiap kesalahan konyol yang bisa dilakukan oleh orang lain.

Terus?

Jika menargetkan 2 lingkungan: Browser dan Node;
"use strict"; dan cukup periksa windowatau global; dan dengan jelas menunjukkan bahwa dalam dokumen itu kode Anda hanya mendukung lingkungan ini. Itu dia!

var isBrowser = typeof window !== 'undefined'
    && ({}).toString.call(window) === '[object Window]';

var isNode = typeof global !== "undefined" 
    && ({}).toString.call(global) === '[object global]';

Jika memungkinkan untuk use case Anda; alih-alih deteksi lingkungan; lakukan deteksi fitur sinkron dalam blok coba / tangkap. (ini akan membutuhkan beberapa milidetik untuk dijalankan).

misalnya

function isPromiseSupported() {
    var supported = false;
    try {
        var p = new Promise(function (res, rej) {});
        supported = true;
    } catch (e) {}
    return supported;
}
Onur Yıldırım
sumber
9

Sebagian besar solusi yang diusulkan sebenarnya dapat dipalsukan. Cara yang kuat adalah dengan memeriksa Classproperti internal objek global menggunakan Object.prototype.toString. Kelas internal tidak dapat dipalsukan dalam JavaScript:

var isNode = 
    typeof global !== "undefined" && 
    {}.toString.call(global) == '[object global]';
Fabian Jakobs
sumber
2
Ini akan kembali benar di bawah browserify.
alt
1
Apakah Anda mengujinya? Saya tidak dapat melihat bagaimana browserify dapat mengubah kelas internal suatu objek. Ini membutuhkan perubahan kode dalam JavaScript VM atau overwriting Object.prototype.toStringyang merupakan praktik yang sangat buruk.
Fabian Jakobs
Saya mengujinya. Inilah yang dilakukan browserify: var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};
Vanuan
Anda lihat, di Chrome, ({}.toString.call(window))sama "[object global]".
Vanuan
2
Ini aneh, karena window.toString()menghasilkan"[object Window]"
Vanuan
5

Bagaimana dengan menggunakan objek proses dan memeriksa execPath untuk node?

process.execPath

Ini adalah pathname absolut dari executable yang memulai proses.

Contoh:

/ usr / local / bin / node

Kevin Hakanson
sumber
2
Bagaimana dengan window.process = {execPath: "/usr/local/bin/node"};?
Константин Ван
4

Inilah variasi saya tentang apa yang di atas:

(function(publish) {
    "use strict";

    function House(no) {
        this.no = no;
    };

    House.prototype.toString = function() {
        return "House #"+this.no;
    };

    publish(House);

})((typeof module == 'undefined' || (typeof window != 'undefined' && this == window))
    ? function(a) {this["House"] = a;}
    : function(a) {module.exports = a;});

Untuk menggunakannya, Anda memodifikasi "Rumah" pada baris terakhir kedua menjadi apa pun yang Anda inginkan nama modul berada di browser dan mempublikasikan apa pun yang Anda inginkan nilai modul (biasanya konstruktor atau objek literal) ).

Di browser objek global adalah jendela, dan memiliki referensi untuk dirinya sendiri (ada window.window yang merupakan == jendela). Tampaknya bagi saya ini tidak mungkin terjadi kecuali Anda berada di browser atau di lingkungan yang ingin Anda percaya bahwa Anda berada di browser. Dalam semua kasus lain, jika ada variabel 'modul' global yang dideklarasikan, ia menggunakan variabel itu jika tidak menggunakan objek global.

kybernetikos
sumber
4

Saya menggunakan processuntuk memeriksa node.js seperti itu

if (typeof(process) !== 'undefined' && process.version === 'v0.9.9') {
  console.log('You are running Node.js');
} else {
  // check for browser
}

atau

if (typeof(process) !== 'undefined' && process.title === 'node') {
  console.log('You are running Node.js');
} else {
  // check for browser
}

Didokumentasikan di sini

Chris
sumber
2
process.titledapat diubah
Ben Barkay
Kemudian periksa judul tempat Anda mengubahnya. Atau gunakan process.version
Chris
Jika Anda menulis untuk perpustakaan (seperti seharusnya), Anda tidak akan dapat mengharapkan judulnya
Ben Barkay
3

Pada tulisan ini, jawaban ini lebih merupakan opsi "segera hadir", karena memanfaatkan fitur JavaScript yang sangat baru.

const runtime = globalThis.process?.release?.name || 'not node'
console.log(runtime)

The runtimenilai akan baik nodeatau not node.

Seperti yang disebutkan, ini bergantung pada beberapa fitur JavaScript baru. globalThisadalah fitur final dalam spesifikasi ECMAScript 2020. Chaining / nullish coalescing opsional ( ?bagian dari globalThis.process?.release?.name) didukung di mesin V8, yang dikirimkan bersama Chrome 80. Pada 4/8/2020, kode ini akan bekerja di browser tetapi tidak akan bekerja di Node karena cabang Node 13 menggunakan cabang V8 7.9.xxx. Saya percaya Node 14 (akan dirilis pada 4/21/2020) seharusnya menggunakan V8 8.x +.

Pendekatan ini hadir dengan dosis pembatasan yang sehat saat ini. Namun; kecepatan di mana browser / Node dilepaskan, pada akhirnya akan menjadi one-liner yang andal.

Corey
sumber
1
Ini harus menjadi jawaban yang diterima! dan semua orang harus menggunakan simpul 14 btw
Sceat
2

Node.js memiliki processobjek, jadi selama Anda tidak memiliki skrip lain yang membuat processAnda dapat menggunakannya untuk menentukan apakah kode berjalan pada Node.

var isOnNodeJs = false;
if(typeof process != "undefined") {
  isOnNodeJs = true;
}

if(isOnNodeJs){
  console.log("you are running under node.js");
}
else {
  console.log("you are NOT running under node.js");
}
Dariusz Sikorski
sumber
2

Ini adalah cara yang cukup aman dan mudah untuk memastikan kompatibilitas antara javascript sisi-server dan sisi-klien, yang juga akan bekerja dengan browserify, RequireJS atau CommonJS termasuk sisi-klien:

(function(){

  // `this` now refers to `global` if we're in NodeJS
  // or `window` if we're in the browser.

}).call(function(){
  return (typeof module !== "undefined" &&
    module.exports &&
    typeof window === 'undefined') ?
    global : window;
}())
Christophe Marois
sumber
1

Sunting : Mengenai pertanyaan Anda yang diperbarui: "Bagaimana skrip dapat mengetahui apakah skrip tersebut diperlukan sebagai modul commonjs?" Saya tidak berpikir itu bisa. Anda dapat memeriksa apakah exportsobjek ( if (typeof exports === "object")), karena spec mengharuskannya disediakan untuk modul, tetapi yang memberitahu Anda adalah ... exportsadalah objek. :-)


Jawaban asli:

Saya yakin ada beberapa simbol khusus NodeJS ( EventEmitter, mungkin tidak, Anda harus menggunakan requireuntuk mendapatkan modul acara; lihat di bawah ) yang dapat Anda periksa, tetapi seperti kata David, idealnya Anda lebih baik mendeteksi fitur (bukan daripada lingkungan) jika masuk akal untuk melakukannya.

Pembaruan : Mungkin sesuatu seperti:

if (typeof require === "function"
    && typeof Buffer === "function"
    && typeof Buffer.byteLength === "function"
    && typeof Buffer.prototype !== "undefined"
    && typeof Buffer.prototype.write === "function") {

Tapi itu hanya memberitahu Anda bahwa Anda berada dalam lingkungan dengan requiredan sesuatu yang sangat, sangat mirip dengan NodeJS Buffer. :-)

TJ Crowder
sumber
Saya masih dapat memecahnya dengan mengatur semua hal itu di Website ... itu hanya berlebihan;) Memeriksa berada di Browser lebih mudah karena lingkungan Node lebih bersih.
Ivo Wetzel
1
@Ivo: Ya, lihat kalimat terakhir saya. Saya dapat dengan mudah mematahkan cek Anda dengan mendefinisikan windowvariabel dalam aplikasi NodeJS. :-)
TJ Crowder
1
@Ivo: Saya tidak akan berada di semua terkejut jika seseorang didefinisikan windowdalam modul NodeJS, sehingga mereka dapat mencakup kode yang mengandalkan windowmenjadi obyek global dan tidak ingin memodifikasi kode tersebut. Saya tidak akan melakukannya, Anda tidak akan melakukannya, tetapi saya yakin seseorang melakukannya. :-) Atau mereka baru saja windowberarti sesuatu yang lain sama sekali.
TJ Crowder
1
@Ivo : yuiblog.com/blog/2010/04/09/... adalah salah satu alasan mengapa objek jendela dapat didefinisikan dalam node.js
slebetman
1
@TJCrowdertypeof process !== "undefined" && process.title === "node"
Raynos
0
const isNode =
  typeof process !== 'undefined' &&
  process.versions != null &&
  process.versions.node != null;
BATANG
sumber
-1

Ambil sumber node.js dan ubah untuk mendefinisikan variabel like runningOnNodeJS . Periksa variabel itu dalam kode Anda.

Jika Anda tidak dapat memiliki node.js versi pribadi Anda sendiri, buka permintaan fitur di proyek. Tanyakan apakah mereka mendefinisikan variabel yang memberi Anda versi node.js yang Anda jalankan. Kemudian periksa variabel itu.

Aaron Digulla
sumber
1
Itu lagi tidak menyelesaikan masalahnya (pada dasarnya tidak terpecahkan), saya dapat kembali membuat variabel di Browser. Cara yang lebih baik adalah mencegah skrip membuat windowglobal, saya kira saya akan mengajukan permintaan fitur pada yang itu.
Ivo Wetzel
@Ivo: Itu ide buruk yang akan memecah kode yang menggunakan jsdom ( github.com/tmpvar/jsdom ) untuk melakukan manipulasi dom sisi server menggunakan perpustakaan yang sudah dikenal seperti YUI dan jQuery. Dan ada kode saat ini dalam produksi yang melakukan ini.
Slebetman
@slebetman Tidak itu tidak akan merusak jsdom. Saya berbicara tentang global , seperti dalam no var statement global , contoh kode di sana menggunakan varpernyataan, orang yang baru saja membocorkannya ke namespace global, dan mereka tidak mendapatkan konsep modul mandiri saat itu
Ivo Wetzel
@Ivo itu agak kasar, itu seperti mengatakan kita harus mengambil kemampuan untuk makan kue karena orang menjadi gemuk makan terlalu banyak. Anda harus mengacaukan namespace global untuk mencapai perpustakaan yang akan bekerja antar-modul. Atau Anda bisa membungkus semuanya dalam satu modul, tetapi lalu apa gunanya?
Ben Barkay
-1

Posting yang sangat lama, tetapi saya baru saja menyelesaikannya dengan membungkus pernyataan yang diperlukan dalam try-catch

try {
     var fs = require('fs')
} catch(e) {
     alert('you are not in node !!!')
}
Stef de Vries
sumber
2
Itu tidak benar, Anda dapat menggunakan browserify untuk menggunakan panggilan "nodeish" ()
fat