कैसे जांचें कि क्या कोई स्क्रिप्ट Node.js के तहत चल रही है?


159

मेरे पास एक स्क्रिप्ट है जिसे मुझे Node.js स्क्रिप्ट की आवश्यकता है, जिसे मैं जावास्क्रिप्ट इंजन को स्वतंत्र रखना चाहता हूं।

उदाहरण के लिए, मैं exports.x = y;केवल तभी करना चाहता हूं जब यह Node.js. के तहत चल रहा हो मैं यह परीक्षण कैसे कर सकता हूं?


इस प्रश्न को पोस्ट करते समय, मुझे नहीं पता था कि Node.js मॉड्यूल सुविधा CommonJS पर आधारित है ।

मेरे द्वारा दिए गए विशिष्ट उदाहरण के लिए, एक अधिक सटीक प्रश्न होगा:

एक स्क्रिप्ट कैसे बता सकती है कि क्या यह कॉमनजस मॉड्यूल के रूप में आवश्यक है?


3
मुझे नहीं पता कि आप ऐसा करने की कोशिश क्यों कर रहे हैं, लेकिन अंगूठे के एक नियम के रूप में आपको इंजन डिटेक्शन के बजाय फीचर डिटेक्शन का उपयोग करना चाहिए। quirksmode.org/js/support.html
क्वेंटिन

4
यह वास्तव में फ़ीचर डिटेक्शन को लागू करने के बारे में एक अनुरोध है, लेकिन यह प्रश्न खराब तरीके से बताता है।
मोनोक्रोम

मेरे स्वयं के उपयोग के लिए एक पुस्तकालय प्रकाशित किया, इससे npmjs.com/package/detect-is-node
abhirathore2006


प्रश्न के साथ एक समस्या, और अधिकांश उत्तर, यह धारणा है कि केवल दो संभावनाएं हैं: ब्राउज़र या नोड.जे.ई.एस. ऐसी संभावना है कि यह न तो ब्राउज़र है और न ही Node.js, जैसे कि Oracle जावा नैशोर्न के साथ मामला है। यदि JDK स्थापित है, तो jjs कमांड आपको स्क्रिप्ट चलाने देता है। लेकिन नैशॉर्न और Node.js के बीच कई अंतर हैं इसलिए आप कोई धारणा नहीं बना सकते। और कौन जानता है कि भविष्य क्या विकल्प ला सकता है? फीचर का पता लगाने की जरूरत है।

जवाबों:


80

कॉमनजेएस समर्थन की तलाश में , यह है कि अंडरस्कोरजेएस पुस्तकालय यह कैसे करता है:

संपादित करें: अपने अद्यतन प्रश्न के लिए:

(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._ = _;
    }
})();

यहाँ उदाहरण मॉड्यूल पैटर्न को बरकरार रखता है।


45
यह कॉमनजेएस समर्थन का पता लगाता है, जो ब्राउज़र समर्थन कर सकते हैं।
मिकमेकाना

7
यहाँ एक समस्या है और नेलर "इसे नेल्ड" करता है। मैं ब्राउज़र में CommonJS की कोशिश कर रहा हूं, और मॉड्यूल लोडर मैं डिफाइन मॉड्यूल.एक्सपोर्ट्स का उपयोग कर रहा हूं, इसलिए यह समाधान मुझे गलत तरीके से बताएगा कि मैं नोड में हूं।
मार्क मेलविल

1
@MarkMelville यकीनन, यह वही है जो ओपी पूछ रहा है इसलिए समस्या नहीं है
रोस

13
मेरी तरफ से खराब शब्द। मेरा मतलब है कि इस समाधान के साथ एक समस्या है। ओपी ने इसे स्वीकार किया हो सकता है, लेकिन मैं नहीं।
मार्क मेलविले

7
यह निश्चित रूप से सबसे अच्छा उत्तर नहीं दिया गया है।
user3751385

107

वैसे Node.js में चलने का पता लगाने का कोई विश्वसनीय तरीका नहीं है क्योंकि हर वेबसाइट आसानी से समान चर घोषित कर सकती है, फिर भी, क्योंकि windowNode.js में कोई वस्तु नहीं है, डिफ़ॉल्ट रूप से आप दूसरे रास्ते पर जा सकते हैं और जाँच सकते हैं कि क्या आप किसी अंदर चल रहे हैं ब्राउज़र।

यह मैं उन कामों के लिए उपयोग करता हूं जो एक ब्राउज़र और Node.js के तहत दोनों में काम करना चाहिए:

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

} else {
    window.foo = {};
}

यह अभी भी उस मामले में फट सकता windowहै जो Node.js में परिभाषित किया गया है, लेकिन किसी के ऐसा करने का कोई अच्छा कारण नहीं है , क्योंकि आपको स्पष्ट रूप varसे globalऑब्जेक्ट पर संपत्ति छोड़ने या सेट करने की आवश्यकता होगी ।

संपादित करें

यह पता लगाने के लिए कि क्या आपकी स्क्रिप्ट कॉमनजेएस मॉड्यूल के रूप में आवश्यक है, फिर से आसान नहीं है। केवल आम बात यह निर्दिष्ट करती है कि ए: मॉड्यूल को फ़ंक्शन के लिए कॉल के माध्यम से शामिल किया जाएगा requireऔर बी: मॉड्यूल exportsऑब्जेक्ट पर गुणों के माध्यम से चीजों को निर्यात करता है । अब इसे कैसे लागू किया जाता है यह अंतर्निहित प्रणाली पर छोड़ दिया गया है। Node.js एक अनाम फ़ंक्शन में मॉड्यूल की सामग्री को लपेटता है:

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

देखें: https://github.com/ry/node/blob/master/src/node.js#L325

लेकिन यह पता लगाने की कोशिश करें कि कुछ पागल arguments.callee.toString()सामानों के माध्यम से , बजाय इसके ऊपर मेरे उदाहरण कोड का उपयोग करें जो ब्राउज़र के लिए जांच करता है। Node.js एक तरह से क्लीनर वातावरण है, इसलिए यह संभावना नहीं है कि windowवहाँ घोषित किया जाएगा।


2
के बारे में "Node.js एक तरह से क्लीनर वातावरण है, इसलिए यह संभावना नहीं है कि खिड़की वहां घोषित की जाएगी।": ठीक है, मैं बस यहां यह पता लगाने के लिए एक तरीका ढूंढ रहा हूं कि क्या मेरी स्क्रिप्ट नोड ब्राउज़र द्वारा चलाए जा रहे थे। या एक सादे ब्राउज़र में ... इसका कारण यह है कि मेरे पास URL स्थान की जाँच करने के लिए सेटटाइमआउट का उपयोग करके एक अनंत लूप है, जो एक ब्राउज़र में ठीक है, लेकिन नोड.जेएस स्क्रिप्ट को हमेशा के लिए चालू रखता है ... तो एक खिड़की हो सकती है सभी के बाद एक नोड.जेएस स्क्रिप्ट में :)
एरिक ब्रेकेहियर

1
@ मुझे अत्यधिक संदेह है कि यह वैश्विक दायरे में होगा, इसलिए जब तक आप windowअपने मॉड्यूल की पहली पंक्ति में कुछ आयात नहीं करते हैं, आपको कोई समस्या नहीं होनी चाहिए। आप एक अनाम फ़ंक्शन भी चला सकते हैं और इसके अंदर [[Class]]की जाँच कर thisसकते हैं (केवल गैर-सख्त मोड में काम करता है) "वर्ग" देखें: bonsaiden.github.com/JavaScript-Garden/#typeof
Ivo Wetzel

1
मेरा मुद्दा ओपी से थोड़ा अलग है: मुझे स्क्रिप्ट की आवश्यकता नहीं है, इसे JSDOM द्वारा वैश्विक संदर्भ के रूप में अनुकरणीय विंडो के साथ लोड किया गया है ... यह अभी भी नोड.जेएस + वी 8 द्वारा चलाया जाता है, सामान्य मॉड्यूल की तुलना में एक अलग संदर्भ में।
एरिक ब्रेकेमियर

1
संभवतः ... मैं एक और दिशा गया: 1) अनंत लूप बनाने से बचने के लिए ऑनशास्कॉन्ग ("ऑनशॉस्कैप") के लिए समर्थन का पता लगाएं। अनंत लूप 2 से बचने के लिए) मुख्य नोड .js स्क्रिप्ट में एमुलेटेड विंडो पर ऑनशॉक प्रॉपर्टी सेट करके समर्थन का अनुकरण करें।
एरिक ब्रेकेमर

1
typeof self === 'object'typeof window === 'undefined'वेब वर्कर्स स्कोप में विफल होने के बाद से अधिक सुरक्षित हो सकता है ।
लुईस

45

मैं वर्तमान नोड के एक गलत का पता लगाने जो है से अधिक ठोकर खाई नहीं में नोड-पर्यावरण के बारे में पता इलेक्ट्रॉन एक भ्रामक सुविधा का पता लगाने की वजह से। निम्नलिखित समाधान प्रक्रिया-पर्यावरण को स्पष्ट रूप से पहचानते हैं।


Node.js को ही पहचानें

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

यह पता चलेगा कि क्या आप नोड-प्रक्रिया में चल रहे हैं, क्योंकि process.releaseइसमें "मेटाडेटा से संबंधित [नोड-] रिलीज" शामिल है।

Io.js के स्पॉन के बाद मूल्य process.release.nameभी बन सकते हैं io.js( प्रक्रिया-डॉक्टर देखें )। एक नोड-तैयार वातावरण का उचित पता लगाने के लिए मुझे लगता है कि आपको निम्न प्रकार से जांचना चाहिए:

नोड (> = 3.0.0) या io.js को पहचानें

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

यह कथन नोड 5.5.0, इलेक्ट्रॉन 0.36.9 (नोड 5.1.1 के साथ) और क्रोम 48.0.2564.116 के साथ परीक्षण किया गया था।

नोड (> = 0.10.0) या io.js को पहचानें

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

@ दलुगे की टिप्पणी ने मुझे और सामान्य प्रमाण के बारे में सोचने के लिए प्रेरित किया। यह Node.js> = 0.10 से काम करना चाहिए । मुझे पूर्व संस्करणों के लिए विशिष्ट पहचानकर्ता नहीं मिला।


Ps: मैं उस उत्तर को यहां पोस्ट कर रहा हूं क्योंकि प्रश्न मुझे यहां ले जाता है, हालांकि ओपी एक अलग प्रश्न के उत्तर की खोज कर रहा था।


2
यह अब तक का सबसे विश्वसनीय तरीका लगता है, धन्यवाद। हालांकि केवल संस्करण> = 3.0.0 के लिए काम कर रहा है।
फ़िलिप

@ बाल्गुगे - प्रेरणा के लिए धन्यवाद। मुझे दुर्भाग्य से 0.10 से कम के लिए एक प्रमाण नहीं मिला।
फ्लोरियन ब्रेकिस

3
मैंने प्रतिक्रिया वेबपैक का उपयोग करते हुए पाया, processऔर process.versionबंडल के भीतर मौजूद है, इसलिए मैंने एक अतिरिक्त चेक जोड़ा कि ग्राहक पक्ष में अनिर्धारित process.versionकहां process.release.nodeहै लेकिन सर्वर साइड पर मान के रूप में एक नोड संस्करण है
हारून

@ एरॉन: उस संकेत के लिए धन्यवाद। मैं process.versionचर (प्रतिक्रिया, वेबपैक या प्रतिक्रिया-वेबपैक) की किसी भी परिभाषा को खोजने में सक्षम नहीं था । मैं किसी भी संकेत की सराहना करूंगा जहां संस्करण-चर को उत्तर में जोड़ने के लिए परिभाषित किया गया है। रिलीज पर निर्भर करता है। नोड के लिए बाधाओं पर निर्भर करता है> = 3.xx
फ्लोरिअन ब्रिस्क

2
वन-लाइनर और सुरक्षित:function isNodejs() { return typeof "process" !== "undefined" && process && process.versions && process.versions.node; }
शानदार

25

यह पता लगाने की कोशिश करने में समस्या कि आपका कोड किस वातावरण में चल रहा है, किसी भी वस्तु को संशोधित किया जा सकता है और यह घोषित करना असंभव बना दिया जाता है कि कौन सी वस्तुएं पर्यावरण की मूल निवासी हैं, और जिन्हें कार्यक्रम द्वारा संशोधित किया गया है।

हालाँकि, कुछ तरकीबें हैं जिनसे हम यह पता लगा सकते हैं कि आप किस माहौल में हैं।

अंडरस्कोर लाइब्रेरी में आमतौर पर स्वीकृत समाधान के साथ शुरुआत करते हैं:

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

यह तकनीक सर्वर साइड के लिए वास्तव में पूरी तरह से ठीक है, क्योंकि जब requireफ़ंक्शन को कॉल किया जाता है, तो यह thisऑब्जेक्ट को एक खाली ऑब्जेक्ट पर रीसेट करता है , और moduleआपके लिए फिर से परिभाषित करता है , जिसका अर्थ है कि आपको किसी भी बाहरी छेड़छाड़ के बारे में चिंता करने की आवश्यकता नहीं है। जब तक आपका कोड अंदर लोड हो जाता हैrequire , तब तक आप सुरक्षित हैं।

हालांकि, यह ब्राउज़र पर अलग हो जाता है, क्योंकि कोई भी आसानी से परिभाषित moduleकर सकता है ऐसा लगता है कि यह वह वस्तु है जिसे आप खोज रहे हैं। एक तरफ यह वह व्यवहार हो सकता है जिसे आप चाहते हैं, लेकिन यह यह भी तय करता है कि वैश्विक दायरे में लाइब्रेरी उपयोगकर्ता किस चर का उपयोग कर सकता है। हो सकता है कि कोई उस नाम के साथ एक चर का उपयोग करना चाहता है moduleजो उसके exportsअंदर एक और उपयोग के लिए है। यह संभावना नहीं है, लेकिन हम कौन हैं जो किसी और का उपयोग करने वाले चर का न्याय कर सकते हैं, सिर्फ इसलिए कि दूसरा पर्यावरण उस चर नाम का उपयोग करता है?

हालाँकि, चाल यह है कि यदि हम मान रहे हैं कि आपकी स्क्रिप्ट वैश्विक दायरे में लोड की जा रही है (जो कि अगर यह स्क्रिप्ट टैग के माध्यम से भरी हुई है तो) एक चर को बाहरी बंद में आरक्षित नहीं किया जा सकता है, क्योंकि ब्राउज़र इसकी अनुमति नहीं देता है । अब नोड में याद रखें, thisऑब्जेक्ट एक खाली ऑब्जेक्ट है, फिर भी, moduleचर अभी भी उपलब्ध है। ऐसा इसलिए है क्योंकि यह एक बाहरी बंद में घोषित किया गया है। तो हम एक अतिरिक्त चेक जोड़कर अंडरस्कोर की जांच को ठीक कर सकते हैं:

this.module !== module

इसके साथ, यदि कोई moduleब्राउज़र में वैश्विक दायरे में घोषित करता है, तो उसे thisऑब्जेक्ट में रखा जाएगा, जिससे परीक्षण विफल this.moduleहो जाएगा , क्योंकि , मॉड्यूल के समान ऑब्जेक्ट होगा। नोड पर, this.moduleमौजूद नहीं है, और moduleएक बाहरी बंद के भीतर मौजूद है, इसलिए परीक्षण सफल होगा, क्योंकि वे समकक्ष नहीं हैं।

इस प्रकार, अंतिम परीक्षा है:

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

नोट: जबकि यह अब moduleवैरिएबल को वैश्विक दायरे में स्वतंत्र रूप से उपयोग करने की अनुमति देता है , फिर भी ब्राउज़र में इसे बंद करना संभव है एक नया क्लोजर बनाकर और moduleउसके भीतर घोषणा करके , फिर उस क्लोजर के भीतर स्क्रिप्ट लोड करना। उस बिंदु पर उपयोगकर्ता नोड वातावरण की पूरी तरह से नकल कर रहा है और उम्मीद है कि जानता है कि वे क्या कर रहे हैं और एक नोड शैली की आवश्यकता करने की कोशिश कर रहे हैं। यदि कोड को स्क्रिप्ट टैग में कहा जाता है, तो यह अभी भी किसी भी नए बाहरी क्लोजर से सुरक्षित रहेगा।


2
वाह, आपके वन-लाइनर के प्रत्येक टुकड़े के पीछे तर्क को स्पष्ट रूप से समझाने के लिए धन्यवाद।
जॉन कोम्ब्स

मिल गया Cannot read property 'module' of undefinedक्योंकि यह उदाहरण के लिए मोचा परीक्षणों में अपरिभाषित है
srghma

20

ब्राउज़र में निम्नलिखित काम करता है जब तक कि जानबूझकर, स्पष्ट रूप से तोड़फोड़ नहीं किया जाता है:

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

बैम।


4
var प्रक्रिया = {toString: function () {रिटर्न ’[ऑब्जेक्ट प्रोसेस]’; }};
निक डेसालनिएर्स

1
क्या कोई कारण है जिसके process+''बजाय आप इसका उपयोग करते हैं process.toString()?
हार्मोनिक

3
लगभग। इसके बजाय इसका प्रयोग करें:Object.prototype.toString.call(process)
sospedra

2
यह इस सवाल का सबसे अच्छा जवाब है।
लोरेटोपरसी

3
@ धार्मिक: var process = null;दूसरे मामले को विफल करने का कारण होगा। जावास्क्रिप्ट और जावा दोनों में, अभिव्यक्ति '' + xसमान है x.toString()जब xकि बुरा होने के अलावा , पूर्व का उत्पादन होता है "null"या "undefined"जहां बाद में कोई त्रुटि होती है।
joeytwield

17

यहाँ यह करने के लिए एक बहुत अच्छा तरीका है:

const isBrowser = this.window === this;

यह काम करता है क्योंकि ब्राउज़रों में वैश्विक 'इस' चर का 'विंडो' नामक एक आत्म संदर्भ है। यह आत्म संदर्भ नोड में मौजूद नहीं है।

  • ब्राउज़र में 'यह' वैश्विक वस्तु का एक संदर्भ है, जिसे 'विंडो' कहा जाता है।
  • नोड 'यह' मॉड्यूल.एक्सपोर्ट्स ऑब्जेक्ट का संदर्भ है।
    • 'यह' नहीं है नोड ग्लोबल ऑब्जेक्ट का संदर्भ है, जिसे 'ग्लोबल' कहा जाता है।
    • 'यह' मॉड्यूल वैरिएबल डिक्लेरेशन स्पेस का संदर्भ नहीं है।

उपरोक्त सुझाए गए ब्राउज़र को तोड़ने के लिए आपको निम्नलिखित की तरह कुछ करना होगा

this.window = this;

चेक निष्पादित करने से पहले।


बस क्यों नहीं const isBrowser = this.window !== undefined? और सिद्धांत में नोड मैं this.window = thisसमाधान को बेवकूफ बनाने के लिए कर सकता हूं ।
टायलर लॉन्ग

11

अभी तक एक और पर्यावरण का पता लगाने :

(अर्थ: यहाँ अधिकांश उत्तर ठीक हैं।)

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 ?..
}

थोड़ा पागल सही? आप अधिक ग्लोबल्स के लिए जाँच करके इसे और अधिक क्रिया कर सकते हैं

लेकिन नहीं!

इन सभी को वैसे भी नकली / नकली किया जा सकता है।

उदाहरण के लिए globalवस्तु नकली :

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

यह नोड की मूल वैश्विक वस्तु से संलग्न नहीं होगा, लेकिन यह इसके साथ संलग्न हो जाएगा window एक ब्राउज़र में ऑब्जेक्ट । तो इसका मतलब यह होगा कि आप एक ब्राउज़र के अंदर Node env में हैं।

जिंदगी छोटी है!

क्या हमें परवाह है कि क्या हमारा पर्यावरण नकली है? यह तब होता है जब कुछ बेवकूफ डेवलपर एक वैश्विक चर घोषित करते हैंglobal वैश्विक दायरे में आने वाले वैश्विक । या कुछ दुष्ट देव हमारे एनवी में किसी तरह कोड इंजेक्ट करते हैं।

जब हम इसे पकड़ते हैं तो हम अपने कोड को क्रियान्वित होने से रोक सकते हैं, लेकिन हमारे ऐप की बहुत सारी निर्भरताएं इस में फंस सकती हैं। तो अंततः कोड टूट जाएगा। यदि आपका कोड काफी अच्छा है, तो आपको हर एक मूर्खतापूर्ण गलती की परवाह नहीं करनी चाहिए जो दूसरों द्वारा की जा सकती है।

तो क्या?

यदि 2 वातावरण को लक्षित कर रहे हैं: ब्राउज़र और नोड;
"use strict"; और या तो बस के लिए जाँच करें windowया global; और स्पष्ट रूप से इंगित करें कि डॉक्स में आपका कोड केवल इन वातावरणों का समर्थन करता है। बस!

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

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

यदि आपके उपयोग के मामले में संभव है; पर्यावरण का पता लगाने के बजाय; एक कोशिश / पकड़ ब्लॉक के भीतर तुल्यकालिक सुविधा का पता लगाने। (इन पर अमल करने में कुछ मिलीसेकंड लगेगा)।

जैसे

function isPromiseSupported() {
    var supported = false;
    try {
        var p = new Promise(function (res, rej) {});
        supported = true;
    } catch (e) {}
    return supported;
}

9

अधिकांश प्रस्तावित समाधान वास्तव में नकली हो सकते हैं। Classवैश्विक वस्तु की आंतरिक संपत्ति की जांच करने का एक मजबूत तरीका है Object.prototype.toString। आंतरिक वर्ग को जावास्क्रिप्ट में फेक नहीं किया जा सकता है:

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

2
यह ब्राउजरिफाइ के तहत सही होगा।
ऊँचाई

1
क्या आपने परीक्षण किया? मैं यह नहीं देख सकता कि किसी वस्तु के आंतरिक वर्ग को ब्राउजर कैसे बदल सकता है। इसके लिए जावास्क्रिप्ट वीएम या ओवरराइटिंग में कोड बदलने की आवश्यकता होती है Object.prototype.toStringजो वास्तव में बुरा अभ्यास है।
फेबियन जेकब्स

मैंने इसका परीक्षण किया। यहाँ var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};
ब्राउजर

आप क्रोम में देखते हैं, ({}.toString.call(window))बराबर है "[object global]"
वानुआन

2
यह अजीब है, क्योंकि window.toString()उत्पादन होता है"[object Window]"
वानुआन

5

क्या प्रक्रिया वस्तु का उपयोग करने और जांच करने के बारे execPath के लिए node?

process.execPath

यह निष्पादन योग्य का पूर्ण पथनाम है जिसने प्रक्रिया शुरू की है।

उदाहरण:

/ Usr / स्थानीय / bin / नोड


2
किस बारे में window.process = {execPath: "/usr/local/bin/node"};?
Константин Ван

4

एक स्क्रिप्ट यह कैसे बता सकती है कि क्या यह एक सामान्य मॉड्यूल के रूप में आवश्यक है?

संबंधित: यह जांचने के लिए कि क्या इसे नोड में सीधे तौर पर चलाए जा रहे मॉड्यूल बनाम के रूप में आवश्यक है, आप देख सकते हैं require.main !== modulehttp://nodejs.org/docs/latest/api/modules.html#accessing_the_main_module


4

यहाँ ऊपर क्या है पर मेरी भिन्नता है:

(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;});

इसका उपयोग करने के लिए, आप "हाउस" को दूसरी अंतिम पंक्ति में संशोधित करते हैं, जो भी आप चाहते हैं कि मॉड्यूल का नाम ब्राउज़र में हो और आप जो भी मॉड्यूल का मान चाहते हैं उसे प्रकाशित करें (आमतौर पर एक निर्माता या एक वस्तु शाब्दिक) )।

ब्राउज़रों में वैश्विक ऑब्जेक्ट विंडो होती है, और इसमें स्वयं का संदर्भ होता है (इसमें एक विंडो है। यह है जो == विंडो है)। यह मुझे लगता है कि यह तब तक होने की संभावना नहीं है जब तक कि आप एक ब्राउज़र में या एक वातावरण में नहीं होते हैं जो चाहता है कि आप विश्वास करें कि आप एक ब्राउज़र में हैं। अन्य सभी मामलों में, यदि कोई वैश्विक 'मॉड्यूल' वैरिएबल घोषित किया गया है, तो वह इसका उपयोग करता है अन्यथा यह वैश्विक ऑब्जेक्ट का उपयोग करता है।


4

मैं processनोड के लिए जाँच करने के लिए उपयोग कर रहा हूँ। जेएस ऐसा

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

या

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

यहां दस्तावेज दिया गया है


2
process.titleबदला जा सकता है
बेन बर्काय

फिर उस शीर्षक के लिए जाँच करें जिसे आपने इसे बदल दिया है। या प्रक्रिया का उपयोग करें। विसर्जन
क्रिस '

यदि आप एक पुस्तकालय (जैसे आपको चाहिए) के लिए लिख रहे हैं, तो आप यह उम्मीद नहीं कर पाएंगे कि शीर्षक क्या होना चाहिए
बेन बार्क

3

इस लेखन के रूप में, यह उत्तर "जल्द ही आने वाला" विकल्प से अधिक है, क्योंकि यह जावास्क्रिप्ट की बहुत नई विशेषताओं का लाभ उठाता है।

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

runtimeमूल्य हो जाएगा या तो nodeया not node

जैसा कि उल्लेख किया गया है, यह कुछ नई जावास्क्रिप्ट विशेषताओं पर निर्भर करता है। globalThisECMAScript 2020 कल्पना में एक अंतिम रूप है। वैकल्पिक जंजीर / nullish coalescing (का ?हिस्सा)globalThis.process?.release?.name ) V8 इंजन में समर्थित है, जो क्रोम 80 के साथ जहाज करता है। 4/8/2020 तक, यह कोड ब्राउज़र में काम करेगा, लेकिन Node 13 शाखा के उपयोग से नोड में काम नहीं करेगा। V8 7.9.xxx। मेरा मानना ​​है कि नोड 14 (4/21/2020 को रिलीज़ होने के कारण) V8 8.x + का उपयोग करने वाला है।

यह दृष्टिकोण वर्तमान प्रतिबंधों की एक स्वस्थ खुराक के साथ आता है। तथापि; जिस गति से ब्राउज़र / नोड जारी किए जाते हैं, वह अंततः एक विश्वसनीय वन-लाइनर होगा।


1
यह स्वीकृत उत्तर होना चाहिए! और हर कोई नोड 14 btw का उपयोग करना चाहिए
Sceat

2

Node.js में processऑब्जेक्ट है, इसलिए जब तक आपके पास कोई अन्य स्क्रिप्ट नहीं है जो बनाते हैं processआप यह निर्धारित करने के लिए उपयोग कर सकते हैं कि कोड नोड पर चलता है या नहीं।

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");
}

2

यह सर्वर-साइड और क्लाइंट-साइड जावास्क्रिप्ट के बीच संगतता सुनिश्चित करने का एक बहुत ही सुरक्षित और सीधे-आगे का तरीका है, जो ब्राउजरिफाई, रिक्वायरमेंट्स या कॉमनजेस के साथ भी काम करेगा, जिसमें क्लाइंट-साइड शामिल हैं:

(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;
}())

1

संपादित करें : अपने अद्यतन किए गए प्रश्न के बारे में: "एक स्क्रिप्ट कैसे बता सकती है कि क्या यह एक सामान्य मॉड्यूल के रूप में आवश्यक है?" मुझे नहीं लगता कि यह हो सकता है। आप जांच सकते हैं कि क्या exportsकोई वस्तु है ( if (typeof exports === "object")), क्योंकि युक्ति की आवश्यकता है कि इसे मॉड्यूल को प्रदान किया जाए, लेकिन यह सब आपको बताता है कि ... exportsएक वस्तु है। :-)


मूल उत्तर:

मुझे यकीन है कि कुछ NodeJS- विशिष्ट प्रतीक हैं ( EventEmitter, शायद नहीं, आपको requireइवेंट मॉड्यूल प्राप्त करने के लिए उपयोग करना होगा। नीचे देखें ) जिसे आप जांच सकते हैं, लेकिन जैसा कि डेविड ने कहा, आदर्श रूप से आप सुविधा का पता लगाने में बेहतर हैं (बल्कि पर्यावरण से) अगर ऐसा करने का कोई मतलब है।

अद्यतन : शायद कुछ इस तरह:

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

लेकिन यह सिर्फ आपको बताता है कि आप एक वातावरण में हैं requireऔर बहुत कुछ, बहुत पसंद है NodeJS की Buffer। :-)


मैं अभी भी उस सभी सामान को एक वेबसाइट में सेट करके तोड़ सकता हूं ... वह बस ओवरकिल है;) एक ब्राउज़र में होने की जांच करना आसान है क्योंकि नोड वातावरण क्लीनर है।
इवो ​​वेटजेल

1
@ आईवो: हां, मेरा आखिरी वाक्य देखें। मैं बस के रूप में आसानी से windowएक NodeJS आवेदन के भीतर एक चर को परिभाषित करके अपनी जांच को तोड़ सकता है । :-)
टीजे क्राउडर

1
@Ivo: अगर कोई NodeJS मॉड्यूल में किसी को परिभाषित करता है, तो मुझे बिल्कुल आश्चर्य नहीं होगा window, इसलिए वे उस कोड को शामिल कर सकते हैं windowजो वैश्विक ऑब्जेक्ट होने पर निर्भर था और उस कोड को संशोधित नहीं करना चाहता था। मैं ऐसा नहीं करूँगा, आप नहीं करेंगे, लेकिन मुझे यकीन है कि किसी के पास है। :-) या वे अभी windowपूरी तरह से कुछ और मतलब है।
टीजे क्राउडर

1
@ आईवो: yuiblog.com/blog/2010/04/09// एक कारण है कि विंडो ऑब्जेक्ट को नोड में परिभाषित किया जा सकता है। जेएस
स्लीबेटमैन

1
@TJCrowdertypeof process !== "undefined" && process.title === "node"
रेयानोस

0
const isNode =
  typeof process !== 'undefined' &&
  process.versions != null &&
  process.versions.node != null;


-1

नोड का स्रोत ले लो ।js और इसे बदलने के लिए एक चर की तरह परिभाषित करें runningOnNodeJS। अपने कोड में उस चर की जाँच करें।

यदि आपके पास अपना निजी संस्करण नोड.जेएस नहीं है, तो परियोजना में एक सुविधा अनुरोध खोलें। पूछें कि वे एक चर को परिभाषित करते हैं जो आपको नोड.जेएस का संस्करण देता है जो आप में चल रहे हैं। फिर उस चर की जांच करें।


1
वह फिर से अपनी (मूल रूप से बेकार) समस्या को हल नहीं करता है, मैं फिर से ब्राउज़र में इस तरह का एक चर बना सकता हूं। बेहतर तरीका यह होगा कि स्क्रिप्ट को windowवैश्विक बनाने से रोका जाए , मुझे लगता है कि मैं उस पर एक फीचर अनुरोध दर्ज करने वाला हूं।
इवो ​​वेटजेल

@ आईवो: यह एक बुरा विचार है जो YUI और jQuery जैसे परिचित पुस्तकालयों का उपयोग करते हुए सर्वर साइड डोम हेरफेर करने के लिए jsdom ( github.com/tmpvar/jsdom ) का उपयोग करने वाले कोड को तोड़ देगा । और वर्तमान में उत्पादन में कोड हैं जो ऐसा करता है।
स्लीवेटमैन

@slebetman नहीं, यह jsdom नहीं तोड़ेगा। मैं ग्लोबल की बात कर रहा हूं , जैसे कोई var स्टेटमेंट ग्लोबल में नहीं है , उदाहरण कोड वहां varस्टेटमेंट का उपयोग करता है , जो लोग इसे सिर्फ ग्लोबल नेमस्पेस में लीक करते हैं, अच्छी तरह से उन्हें तब स्व-निहित मॉड्यूल की अवधारणा नहीं मिलती है
Ivo Wetzel

@ अगर वह हिंसक है, तो यह कहने जैसा है कि हमें केक खाने की क्षमता लेनी चाहिए क्योंकि लोग उन्हें खाने से मोटे हो जाते हैं। आप चाहिए एक पुस्तकालय है कि अंतर-मॉड्यूल काम करेंगे प्राप्त करने के लिए वैश्विक नामस्थान को अस्त-व्यस्त। या आप इसे एक ही मॉड्यूल में लपेट सकते हैं, लेकिन तब क्या बात है?
बेन बर्काय

-1

बहुत पुरानी पोस्ट, लेकिन मैंने कोशिश-कैच में आवश्यक बयानों को लपेटकर इसे हल किया

try {
     var fs = require('fs')
} catch(e) {
     alert('you are not in node !!!')
}

2
यह सच नहीं है, आप "निटिश" आवश्यकता () कॉल
वसा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.