410

以外process.cwd()に、現在のプロジェクトのルート ディレクトリのパス名を取得する別の方法はありますか。Node は ruby​​ のプロパティのようなものを実装していますかRails.root? 一定で信頼できるものを探しています。

4

32 に答える 32

769

これには多くの方法があり、それぞれに長所と短所があります。

require.main.filename

http://nodejs.org/api/modules.htmlから:

ファイルがノードから直接実行require.mainされると、そのmodule. つまり、テストによってファイルが直接実行されたかどうかを判断できます。require.main === module

modulefilenameプロパティ (通常は と同等) を提供するため__filename、現在のアプリケーションのエントリ ポイントは をチェックすることで取得できますrequire.main.filename

したがって、アプリのベース ディレクトリが必要な場合は、次のようにします。

const { dirname } = require('path');
const appDir = dirname(require.main.filename);

長所短所

これはほとんどの場合うまく機能しますが、アプリをpm2などのランチャーで実行している場合やmochaテストを実行している場合、この方法は失敗します。

module.paths

Node は、すべてのモジュール検索パスを に公開しますmodule.paths。これらをトラバースして、最初に解決したものを選択できます。

async function getAppPath() {
  const { dirname } = require('path');
  const { constants, promises: { access } } = require('fs');
  
  for (let path of module.paths) {
    try {
      await access(path, constants.F_OK);
      return dirname(path);
    } catch (e) {
      // Just move on to next path
    }
  }
}

長所短所

これは機能することもありますが、アプリケーションがインストールされているディレクトリではなく、パッケージがインストールされているディレクトリを返す可能性があるため、パッケージで使用すると信頼できません。

グローバル変数の使用

Node には、という名前のグローバル名前空間オブジェクトglobalがあります。このオブジェクトにアタッチするものはすべて、アプリ内のどこでも使用できます。そのため、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');

長所短所

一貫して動作しますが、グローバル変数に依存する必要があります。つまり、コンポーネントなどを簡単に再利用することはできません。

process.cwd()

これは、現在の作業ディレクトリを返します。プロセスが起動されたディレクトリに完全に依存するため、まったく信頼できません。

$ 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というノード モジュールを作成しました。使い方は簡単です:

const appRoot = require('app-root-path');
const myModule = require(`${ appRoot }/lib/my-module.js`);

app-root-pathモジュールは、いくつかの手法を使用して、グローバルにインストールされたモジュールを考慮して、アプリのルート パスを決定します (たとえば、アプリが で実行されている/var/www/が、モジュールが にインストールされている場合~/.nvm/v0.x.x/lib/node/)。100% の場合は機能しませんが、ほとんどの一般的なシナリオでは機能します。

長所短所

ほとんどの状況で構成なしで動作します。また、いくつかの便利な追加メソッドも提供します (プロジェクト ページを参照)。最大の短所は、次の場合に機能しないことです。

  • pm2 などのランチャーを使用している
  • AND、モジュールがアプリのnode_modulesディレクトリ内にインストールされていない (たとえば、グローバルにインストールした場合)

APP_ROOT_PATH環境変数を設定するか.setPath()、モジュールを呼び出すことでこれを回避できますが、その場合は、おそらくglobalメソッドを使用する方がよいでしょう。

NODE_PATH 環境変数

現在のアプリのルート パスを特定する方法を探している場合は、上記の解決策のいずれかが最適です。一方、アプリ モジュールを確実にロードする問題を解決しようとしている場合は、NODE_PATH環境変数を調べることを強くお勧めします。

ノードのモジュール システムは、さまざまな場所でモジュールを探します。 これらの場所の 1 つは、process.env.NODE_PATH指している場所です。この環境変数を設定するrequireと、他の変更を加えることなく、標準のモジュール ローダーでモジュールを作成できます。

たとえば、 に設定NODE_PATHする/var/www/libと、次のようにすると問題なく動作します。

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

これを行うための優れた方法は、次を使用することですnpm

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

これでアプリを開始でき、npm startゴールデンです。これを自分のenforce-node-pathモジュールと組み合わせて、設定せずにアプリを誤ってロードするのを防ぎNODE_PATHます。環境変数の適用をさらに制御するには、checkenvを参照してください。

1 つの落とし穴: ノード アプリの外部で設定するNODE_PATH 必要があります。モジュールローダーは、アプリの実行前に検索するディレクトリのリストをキャッシュするため、次のようなことはできません。process.env.NODE_PATH = path.resolve(__dirname)

[2016 年 4 月 6 日追加]この問題を解決しようとするもう 1 つの非常に有望なモジュールはwavyです。

于 2013-09-10T14:22:58.777 に答える
71

__dirnameグローバルではありません。現在のモジュールに対してローカルであるため、各ファイルには独自のローカルの異なる値があります。

実行中のプロセスのルート ディレクトリが必要な場合は、おそらくprocess.cwd().

予測可能性と信頼性が必要な場合は、おそらく、特定の環境変数が設定されていることをアプリケーションの要件にする必要があります。あなたのアプリはMY_APP_HOME(または何でも)探し、そこにあり、アプリケーションがそのディレクトリに存在する場合は、すべて問題ありません。定義されていない場合、またはディレクトリにアプリケーションが含まれていない場合は、ユーザーに変数を作成するように求めるエラーが表示されて終了します。インストールプロセスの一部として設定できます。

のようなものでノードの環境変数を読み取ることができますprocess.env.MY_ENV_VARIABLE

于 2013-06-07T15:45:20.877 に答える
57

1- プロジェクト ルートにファイルを作成し、それをsettings.jsと呼びます

2-このファイル内にこのコードを追加します

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

3- node_modules 内で「settings」という名前の新しいモジュールを作成し、モジュール index.js 内で次のコードを記述します。

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

4-そして、プロジェクトディレクトリが必要なときはいつでも

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

このようにして、このファイルに関連するすべてのプロジェクト ディレクトリが作成されます ;)

于 2013-08-18T23:20:04.623 に答える
42

単純:

require('path').resolve('./')
于 2020-06-14T20:51:07.667 に答える
39

グローバル ルートを取得する最も簡単な方法 ( NPM を使用して node.js アプリ 'npm start' などを実行すると仮定)

var appRoot = process.env.PWD;

上記を相互検証したい場合

process.env.PWDnode.js アプリケーションの設定をクロスチェックしたいとします。実行時テストで の有効性を確認したい場合はprocess.env.PWD、このコード (私が書いたもので、うまく機能しているようです) を使用してクロスチェックできます。appRoot の最後のフォルダーの名前と package.json ファイルの npm_package_name を照合できます。次に例を示します。

    var path = require('path');

    var globalRoot = __dirname; //(you may have to do some substring processing if the first script you run is not in the project root, since __dirname refers to the directory that the file is in for which __dirname is called in.)

    //compare the last directory in the globalRoot path to the name of the project in your package.json file
    var folders = globalRoot.split(path.sep);
    var packageName = folders[folders.length-1];
    var pwd = process.env.PWD;
    var npmPackageName = process.env.npm_package_name;
    if(packageName !== npmPackageName){
        throw new Error('Failed check for runtime string equality between globalRoot-bottommost directory and npm_package_name.');
    }
    if(globalRoot !== pwd){
        throw new Error('Failed check for runtime string equality between globalRoot and process.env.PWD.');
    }

この NPM モジュールを使用することもできます。require('app-root-path')これは、この目的に非常に適しています。

于 2015-05-26T18:14:14.337 に答える
13

これらすべての「ルートディレクトリ」は、ほとんどの場合、実際のパイルパスへの仮想パスを解決する必要があるため、次を確認する必要がありますpath.resolveか?

var path= require('path');
var filePath = path.resolve('our/virtual/path.ext');
于 2014-04-18T13:10:30.617 に答える
9

__filenameが見つかるまでから上に移動してみてpackage.json、それが現在のファイルが属するメイン ディレクトリであると判断することもできます。

于 2015-06-19T16:04:45.493 に答える
1

メイン ファイルの先頭に次を追加します。

mainDir = __dirname;

次に、必要なファイルで使用します。

console.log('mainDir ' + mainDir);
  • mainDirはグローバルに定義されています。現在のファイルでのみ必要な場合は、__dirname代わりに使用してください。
  • メイン ファイルは通常、プロジェクトのルート フォルダーにあり、、、などの名前が付けられmain.jsます。index.jsgulpfile.js
于 2016-05-28T06:58:54.063 に答える
1

node_modulesこれにより、通常はプロジェクト ルートを示すディレクトリが含まれるまで、ディレクトリ ツリーが下に移動します。

const fs = require('fs')
const path = require('path')

function getProjectRoot(currentDir = __dirname.split(path.sep)) {
  if (!currentDir.length) {
    throw Error('Could not find project root.')
  }
  const nodeModulesPath = currentDir.concat(['node_modules']).join(path.sep)
  if (fs.existsSync(nodeModulesPath) && !currentDir.includes('node_modules')) {
    return currentDir.join(path.sep)
  }
  return this.getProjectRoot(currentDir.slice(0, -1))
}

またnode_modules、ネストされたパッケージのインストールに含まれていることを意味するため、返されたパスに no がないことも確認します。

于 2020-04-25T17:59:49.440 に答える
0

私はこれを使います。

私のモジュールの名前mymodule

var BASE_DIR = __dirname.replace(/^(.*\/mymodule)(.*)$/, '$1')

于 2016-12-02T15:08:23.713 に答える
0

これは次のようになります。

path.join(...process.argv[1].split(/\/|\\/).slice(0, -1))
于 2019-10-01T21:13:47.647 に答える
0

Express アプリ変数にルート ディレクトリ パスを追加するだけで、アプリからこのパスを取得できます。このためapp.set('rootDirectory', __dirname);に、index.js または app.js ファイルに追加します。req.app.get('rootDirectory')また、コードでルート ディレクトリ パスを取得するために使用します。

于 2018-06-24T10:15:19.480 に答える
-1

試すpath._makeLong('some_filename_on_root.js');

例:

cons path = require('path');
console.log(path._makeLong('some_filename_on_root.js');

これにより、ノード アプリケーションのルートからのフル パスが返されます (package.json の同じ位置)。

于 2016-06-28T18:38:36.700 に答える
-1

使用するだけです:

 path.resolve("./") ... output is your project root directory
于 2018-10-10T09:34:49.943 に答える