Gereksinim üzerinden veya doğrudan komut satırından çağrılırsa algılama


Yanıtlar:


473
if (require.main === module) {
    console.log('called directly');
} else {
    console.log('required as a module');
}

Bunun için belgelere bakın: https://nodejs.org/docs/latest/api/modules.html#modules_accessing_the_main_module


3
Bu aşmanın bir yolu var mı? Bunu yapan (ki ben üzerinde kontrol yok) kodu var, ama () gerek ve doğrudan çağrılmış gibi hareket var. Temel olarak, bu testi kullanan bir şeyi doğrudan denir diye düşünmeye kandırmam gerekiyor.
Kevin

2
@Kevin Bunu yapmayı bilmiyorum require(), ama dosyayı alıp sonra çalıştırarak evalveya çalıştırarak yapabilirsinrequire('child_process').exec('node the_file.js')
MalcolmOcean

ES modüllerini Node.js ile kullanırken, es-mainbir modülün doğrudan çalıştırılıp çalıştırılmadığını kontrol etmek için paketi kullanabilirsiniz .
Tim Schaub

91

Başka, biraz daha kısa bir yol var (belirtilen dokümanlarda ana hatlarıyla belirtilmemiş).

var runningAsScript = !module.parent;

Tüm bunların bu blog gönderisinde başlık altında nasıl çalıştığı hakkında daha ayrıntılı bilgi verdim .


+1, bunu daha çok seviyorum, ancak kabul edilen cevapları değiştirmeden önce tereddüt edeceğim. :)
Bryan Field

8
Belirttiğim gibi, belgelenen resmi yol @nicolaskruchten ana hatlarıdır. Bu sadece bir alternatif, kabul edilen cevabı değiştirmeye gerek yok. Her ikisi de çalışır.
Thorsten Lorenz

10
Belgelenmiş yol yerine bunu kullanmak zorunda kaldım - belgelenmiş yol örneğin işe yarıyor. node script.jsama değil cat script.js | node. Bu şekilde her ikisi için de çalışır.
Tim Malone

9

Açıklamalarda kullanılan terminoloji ile biraz kafam karışmıştı. Bu yüzden birkaç hızlı test yapmak zorunda kaldım.

Bunların aynı sonuçları verdiğini buldum:

var isCLI = !module.parent;
var isCLI = require.main === module;

Ve diğer karışık insanlar için (ve soruyu doğrudan cevaplamak için):

var isCLI = require.main === module;
var wasRequired = !isCLI;

5

Tıpkı Python'da olduğu gibi, kendimi her zaman bu kahrolası kod parçacığını nasıl yazacağımı hatırlamaya çalışırken buluyorum. Bu yüzden bunun için basit bir modül oluşturmaya karar verdim. Arayanın modül bilgilerine erişmek hiç de kolay olmadığı için geliştirmemiz biraz zaman aldı, ancak bunun nasıl yapılabileceğini görmek eğlenceliydi.

Buradaki fikir, bir modülü çağırmak ve arayan modülün ana modül olup olmadığını sormaktır. Arayan fonksiyonunun modülünü bulmalıyız. İlk yaklaşımım kabul edilen cevabın bir varyasyonuydu:

module.exports = function () {
    return require.main === module.parent;
};

Ancak bunun çalışması garanti edilmez. bizi hafızaya yükleyenmodule.parent modüle işaret ediyor, bizi arayan modül değil. Bu yardımcı modülü belleğe yükleyen arayan modülü olsaydı, sorun değil. Ama öyle değilse, çaresiziz. Bu yüzden başka bir şey denememiz gerekiyor. Benim çözüm bir yığın izleme oluşturmak ve oradan arayanın modül adını almak oldu:

module.exports = function () {
    // generate a stack trace
    const stack = (new Error()).stack;
    // the third line refers to our caller
    const stackLine = stack.split("\n")[2];
    // extract the module name from that line
    const callerModuleName = /\((.*):\d+:\d+\)$/.exec(stackLine)[1];

    return require.main.filename === callerModuleName;
};

Şimdi yapabiliriz:

if (require("./is-main-module")()) {  // notice the `()` at the end
    // do something
} else {
    // do something else
}

Veya daha okunabilir:

const isMainModule = require("./is-main-module");

if (isMainModule()) {
    // do something
} else {
    // do something else
}

Unutmak imkansız :-)


2
Çok havalı. Ortak kod parçacıkları tek bir adla kısaltılırken seviyorum. Küçük ayar:return require.main /*this is undefined if we started node interactively*/ && require.main.filename === callerModuleName;
masterxilo

4

ES6 modülleri kullanıyorsanız bunu deneyin:

if (process.mainModule.filename === __filename) {
  console.log('running as main module')
}

2
bok, benim process.mainModuleisundefined
datdinhquoc

1
GHOSHHHH, bunu benim .mjs dosyamda kontrol etmem gerekiyor
datdinhquoc
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.