從執行的node.js應用程式確定專案根目錄

xfxf996發表於2020-08-18

本文翻譯自:Determine project root from a running node.js application

Is there a better way than process.cwd() to determine the root directory of a running node.js process? 有沒有比process.cwd()更好的方法來確定正在執行的node.js程式的根目錄? Something like the equivalent of Rails.root , but for Node.js. 類似於Rails.root ,但適用於Node.js。 I'm looking for something that is as predictable and reliable as possible. 我正在尋找儘可能可預測和可靠的東西。


#1樓

參考:https://stackoom.com/question/H4Bo/從執行的node-js應用程式確定專案根目錄


#2樓

__dirname isn't a global; __dirname不是全域性的; it's local to the current module so each file has its own local, different value. 它在當前模組本地,因此每個檔案都有其自己的本地值。

If you want the root directory of the running process, you probably do want to use process.cwd() . 如果要執行的程式的根目錄,則可能確實要使用process.cwd()

If you want predictability and reliability, then you probably need to make it a requirement of your application that a certain environment variable is set. 如果需要可預測性和可靠性,則可能需要使您的應用程式要求設定某個環境變數。 Your app looks for MY_APP_HOME (Or whatever) and if it's there, and the application exists in that directory then all is well. 您的應用程式查詢MY_APP_HOME (或其他),如果存在,並且該應用程式存在於該目錄中,則一切正常。 If it is undefined or the directory doesn't contain your application then it should exit with an error prompting the user to create the variable. 如果未定義或目錄不包含您的應用程式,則它應退出並出現錯誤提示使用者建立變數。 It could be set as a part of an install process. 可以將其設定為安裝過程的一部分。

You can read environment variables in node with something like process.env.MY_ENV_VARIABLE . 您可以使用諸如process.env.MY_ENV_VARIABLE類的內容讀取節點中的環境變數。


#3樓

1- create a file in the project root call it settings.js 1-在專案根目錄中建立一個檔案,將其稱為settings.js

2- inside this file add this code 2-在此檔案中新增此程式碼

module.exports = {
    POST_MAX_SIZE : 40 , //MB
    UPLOAD_MAX_FILE_SIZE: 40, //MB
    PROJECT_DIR : __dirname
};

3- inside node_modules create a new module name it "settings" and inside the module index.js write this code: 3-在node_modules內部建立一個新的模組名稱,即“設定”,並在模組index.js內部編寫以下程式碼:

module.exports = require("../../settings");

4- and any time you want your project directory just use 4-以及您希望專案目錄僅使用的任何時間

var settings = require("settings");
settings.PROJECT_DIR; 

in this way you will have all project directories relative to this file ;) 這樣,您將擁有與此檔案相關的所有專案目錄;)


#4樓

There are several ways to approach this, each with their own pros and cons: 有幾種方法可以解決此問題,每種方法各有利弊:

require.main.filename require.main.filename

From http://nodejs.org/api/modules.html : 來自http://nodejs.org/api/modules.html

When a file is run directly from Node, require.main is set to its module . 直接從Node執行檔案時,將require.main設定為其module That means that you can determine whether a file has been run directly by testing require.main === module 這意味著您可以通過測試require.main === module來確定檔案是否已直接執行。

Because module provides a filename property (normally equivalent to __filename ), the entry point of the current application can be obtained by checking require.main.filename . 由於module提供了filename屬性(通常等效於__filename ),因此可以通過檢查require.main.filename來獲取當前應用程式的入口點。

So if you want the base directory for your app, you can do: 因此,如果您想要應用程式的基本目錄,則可以執行以下操作:

var path = require('path');
var appDir = path.dirname(require.main.filename);

Pros & Cons 優點缺點

This will work great most of the time, but if you're running your app with a launcher like pm2 or running mocha tests, this method will fail. 在大多數情況下,這會很好用,但是如果您使用pm2之類的啟動器執行應用程式或執行mocha測試,則此方法將失敗。

global.X 全域性X

Node has aa global namespace object called global — anything that you attach to this object will be available everywhere in your app. 節點有一個名為global全域性名稱空間物件-您附加到此物件的所有物件都將在您的應用程式中隨處可用。 So, in your index.js (or app.js or whatever your main app file is named), you can just define a global variable: 因此,在index.js (或app.js或主應用程式檔案中的任何名稱)中,您可以定義一個全域性變數:

// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);

// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');

Pros & Cons 優點缺點

Works consistently but you have to rely on a global variable, which means that you can't easily reuse components/etc. 可以始終如一地工作,但是您必須依賴全域性變數,這意味著您無法輕鬆地重用元件/等。

process.cwd() process.cwd()

This returns the current working directory. 這將返回當前工作目錄。 Not reliable at all, as it's entirely dependent on what directory the process was launched from : 完全不可靠,因為它完全取決於程式哪個目錄啟動:

$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir

app-root-path 應用程式根路徑

To address this issue, I've created a node module called app-root-path . 為了解決這個問題,我建立了一個名為app-root-path的節點模組。 Usage is simple: 用法很簡單:

var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');

The app-root-path module uses several different techniques to determine the root path of the app, taking into account globally installed modules (for example, if your app is running in /var/www/ but the module is installed in ~/.nvm/v0.xx/lib/node/ ). app-root-path模組使用幾種不同的技術來確定應用程式的根路徑,同時考慮到全域性安裝的模組(例如,如果您的應用程式在/var/www/執行,但該模組在~/.nvm/v0.xx/lib/node/安裝) ~/.nvm/v0.xx/lib/node/ )。 It won't work 100% of the time, but it's going to work in most common scenarios. 它不會100%地起作用,但是可以在大多數常見情況下起作用。

Pros & Cons 優點缺點

Works without configuration in most circumstances. 在大多數情況下無需配置即可工作。 Also provides some nice additional convenience methods (see project page). 還提供了一些不錯的附加便利方法(請參閱專案頁面)。 The biggest con is that it won't work if: 最大的缺點是,如果出現以下情況,它將不起作用:

  • You're using a launcher, like pm2 您正在使用啟動器,例如pm2
  • AND , the module isn't installed inside your app's node_modules directory (for example, if you installed it globally) AND ,該模組未安裝在您應用的node_modules目錄中(例如,如果您是全域性安裝的)

You can get around this by either setting a APP_ROOT_PATH environmental variable, or by calling .setPath() on the module, but in that case, you're probably better off using the global method. 您可以通過設定APP_ROOT_PATH環境變數或在模組上呼叫.setPath()解決此問題,但在這種情況下,最好使用global方法。

NODE_PATH environmental variable NODE_PATH環境變數

If you're looking for a way to determine the root path of the current app, one of the above solutions is likely to work best for you. 如果您正在尋找一種確定當前應用程式根路徑的方法,則上述解決方案之一可能最適合您。 If, on the other hand, you're trying to solve the problem of loading app modules reliably, I highly recommend looking into the NODE_PATH environmental variable. 另一方面,如果您要解決可靠載入應用程式模組的問題,則我強烈建議您檢視NODE_PATH環境變數。

Node's Modules system looks for modules in a variety of locations. Node的模組系統在各種位置查詢模組。 One of these locations is wherever process.env.NODE_PATH points . 這些位置之一是process.env.NODE_PATH指向的位置 If you set this environmental variable, then you can require modules with the standard module loader without any other changes. 如果設定此環境變數,則可以require具有標準模組載入器的模組,而無需進行任何其他更改。

For example, if you set NODE_PATH to /var/www/lib , the the following would work just fine: 例如,如果將NODE_PATH設定為/var/www/lib ,則可以很好地進行以下操作:

require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js

A great way to do this is using npm : 一個很好的方法是使用npm

"scripts": {
    "start": "NODE_PATH=. node app.js"
}

Now you can start your app with npm start and you're golden. 現在,您可以使用npm start來啟動您的應用程式了,您就很高興。 I combine this with my enforce-node-path module, which prevents accidentally loading the app without NODE_PATH set. 我將其與我的NODE_PATH -node-path模組結合使用,這可以防止在未設定NODE_PATH情況下意外載入應用程式。 For even more control over enforcing environmental variables, see checkenv . 有關對執行環境變數的更多控制,請參見checkenv

One gotcha: NODE_PATH must be set outside of the node app. 一個 NODE_PATH 必須在節點應用程式外部設定NODE_PATH You cannot do something like process.env.NODE_PATH = path.resolve(__dirname) because the module loader caches the list of directories it will search before your app runs. 您無法執行類似process.env.NODE_PATH = path.resolve(__dirname)因為模組載入程式會在應用程式執行之前快取將搜尋的目錄列表。

[added 4/6/16] Another really promising module that attempts to solve this problem is wavy . [16年4月6日新增]試圖解決此問題的另一個非常有前途的模組是波浪形的


#5樓

All these "root dirs" mostly need to resolve some virtual path to a real pile path, so may be you should look at path.resolve ? 所有這些“根目錄”都需要將一些虛擬路徑解析為真實的堆路徑,因此您可能應該看看path.resolve

var path= require('path');
var filePath = path.resolve('our/virtual/path.ext");

#6樓

Create a function in app.js 在app.js中建立一個函式

/*Function to get the app root folder*/

var appRootFolder = function(dir,level){
    var arr = dir.split('\\');
    arr.splice(arr.length - level,level);
    var rootFolder = arr.join('\\');
    return rootFolder;
}

// view engine setup
app.set('views', path.join(appRootFolder(__dirname,1),'views'));

相關文章