実行中のnode.jsプロセスのルートディレクトリを決定するのに、process.cwd()
より良い方法はありますか?Rails.root`に相当するようなもので、Node.js用のものです。できるだけ予測可能で信頼できるものを探しています。
これにはいくつかの方法があり、それぞれに長所と短所がある:
fromhttp://nodejs.org/api/modules.html:
ファイルがNodeから直接実行されると、require.main
はそのmodule
に設定される。つまり、ファイルが直接実行されたかどうかは require.main === module
をテストすることで判断できます。
をテストすることでファイルが直接実行されたかどうかを判断できる;
モジュールは
filenameプロパティ(通常は
__filenameと等価)を提供するので、
require.main.filename` をチェックすることで、現在のアプリケーションのエントリポイントを得ることができる。
そのため、アプリのベースディレクトリが必要な場合は、次のようにすることができる:
var path = require('path');
var appDir = path.dirname(require.main.filename);
これはほとんどの場合うまくいきますが、pm2 のようなランチャーでアプリを実行していたり、mocha テストを実行していたりすると、この方法は失敗します。
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');
一貫して動作するが、グローバル変数に依存しなければならない。
これは現在の作業ディレクトリを返す。 プロセスがどのディレクトリから起動されたかに依存するため、信頼性は低い:
$ 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というnodeモジュールを作成しました。 使い方は簡単です:
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
app-root-path](https://github.com/inxilpro/node-app-root-path)**モジュールは、グローバルにインストールされたモジュール(例えば、アプリが /var/www/
で実行されているが、モジュールが ~/.nvm/v0.x.x/lib/node/
にインストールされている場合)を考慮して、アプリのルートパスを決定するためにいくつかの異なるテクニックを使用します。 100%常にうまくいくわけではありませんが、一般的なシナリオではうまくいくでしょう。
ほとんどの場合、設定なしで動作する。 また、いくつかの便利な追加メソッドも提供する(プロジェクトページを参照)。 最大の欠点は、以下の場合には動作しないことである:
node_modules
ディレクトリにインストールされていない場合。環境変数 APP_ROOT_PATH
を設定するか、モジュールに対して .setPath()
を呼び出すことで回避できますが、その場合は global
メソッドを使用した方が良いでしょう。
もし、現在のアプリのルートパスを決定する方法を探しているのであれば、上記の解決方法のいずれかが最適でしょう。 一方、アプリモジュールを確実にロードする問題を解決したいのであれば、環境変数 NODE_PATH
を調べることを強くお勧めします。
NodeのModules systemは様々な場所でモジュールを探します。 これらの場所の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 を参照してください。
One gotcha: NODE_PATH
must be set outside of the node app. なぜなら、モジュール・ローダーがアプリの実行前に検索するディレクトリのリストをキャッシュするからです。
**この問題を解決しようとするもう一つの有望なモジュールがwavyだ。
dirname`はグローバルなものではなく、現在のモジュールにローカルなものである。
実行中のプロセスのルート・ディレクトリが必要な場合は、process.cwd()
を使うことになるだろう。
予測可能性と信頼性を求めるのであれば、特定の環境変数が設定されていることをアプリケーションの要件にする必要があるだろう。アプリはMY_APP_HOME
(または何でもいい)を探し、もしそれがあり、アプリケーションがそのディレクトリに存在すれば、すべてうまくいく。もしそれが未定義であったり、そのディレクトリにアプリケーションがなかったりすれば、ユーザーに変数を作成するよう促すエラーとともに終了するはずです。インストール・プロセスの一部として設定することもできます。
nodeの環境変数はprocess.env.MY_ENV_VARIABLE
のようなもので読み込むことができる。
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;
こうすることで、すべてのプロジェクト・ディレクトリがこのファイルからの相対パスになります;)
グローバルルートを取得する最も簡単な方法( NPMを使用してnode.jsアプリの「npm start」を実行するとします)。
var appRoot = process.env.PWD;
上記を相互検証したい場合。
process.env.PWD
をnode.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')
は、この目的に非常にうまく機能します。
これは、アプリケーションがサブフォルダーから呼び出された場合でも、Mocha :などのいくつかのテストフレームワークと同様に、一貫して機能することを発見しました。
process.mainModule.paths[0].split('node_modules')[0].slice(0, -1);
それが機能する理由:
実行時に、ノードはすべてのロードされたファイルのフルパスのレジストリを作成します。 モジュールは最初にロードされるため、このレジストリの上部にあります。 レジストリの最初の要素を選択し、「node_modules」ディレクトリの前のパスを返すことにより、アプリケーションのルートを決定できます。
これは1行のコードですが、簡単にするために(私のために)、NPMモジュールにブラックボックス化しました。
https://www.npmjs.com/package/node-root.pddivine。
楽しい。!
これらのすべての「ルートディル」は、実際のパイルパスへの仮想パスを解決する必要があるため、「path.resolve」を確認する必要があります?
var path= require('path');
var filePath = path.resolve('our/virtual/path.ext");
実際、私はおそらく最も堅 ⁇ な解決策も見つけます。 プロジェクトのルートディレクトリに次のファイルを配置するだけです。次のコードを持つroot-path.js:
import * as path from 'path'
const projectRootPath = path.resolve(__dirname)
export const rootPath = projectRootPath
expressを使用するときに役立つと思われる手法は、他のルートを設定する前に、app.jsに以下を追加することです。
// set rootPath
app.use(function(req, res, next) {
req.rootPath = __dirname;
next();
});
app.use('/myroute', myRoute);
globalsを使用する必要はなく、リクエストオブジェクトのプロパティとしてルートディレクトリのパスを持っています。
これは、app.jsがプロジェクトのルートにある場合に機能します。デフォルトでは、ルートです。
これはもう手遅れです。 ただし、ルートURLを2つの方法でフェッチできます。
1番目の方法。
var path = require('path');
path.dirname(require.main.filename);
2番目の方法。
var path = require('path');
path.dirname(process.mainModule.filename);
参照リンク:-https://gist.github.com/geekiam/e2e3e0325abd9023d3a3。
const users = require('../../../database/users'); // 👎 what you have
// OR
const users = require('$db/users'); // 👍 no matter how deep you are
const products = require('/database/products'); // 👍 alias or pathing from root directory
1。 パッケージをインストール: npm install sexy-require --save
< br />。
2。 メインアプリケーションファイルの上部に「require( 'sexy-require')」を1回含めます。
require( 'sexy-require');。
const routers = require( '/ routers');。
const api = require( '$ api');。
...
3。 オプションのステップ。 パス構成は、プロジェクトのルートディレクトリの「.paths」ファイルで定義できます。
$ db = / server / database。
$ api-v1 = / server / api / legacy。
$ api-v2 = / server / api / v2。