2012-10-24 7 views
12

LinuxでAWS EC2のNode.JSアプリケーションを実行し、fsモジュールを使用してHTMLテンプレートファイルを読み込みます。テンプレートは、常にその場所になりますHTMLは、しかし、テンプレート読書サービスが別の場所に動き回ることがNode.JSのアプリケーションルートを基準にファイルを参照する適切な方法

/server.js 
/templates/my-template.html 
/services/template-reading-service.js 

(深いサブディレクトリなど)の中から:ここではアプリケーションの現在の構造は、テンプレート読書サービス私はそうのように、ファイルをロードするためにfs.readFileSync()を使用します。

Error: ENOENT, no such file or directory './templates/my-template.html' 

私は股関節を想定しています:

var templateContent = fs.readFileSync('./templates/my-template.html', 'utf8'); 

これは、次のエラーがスローされますパスは './'がアプリケーションルートではなく '/ services /'ディレクトリに解決されているためです。私はまた、パスを '../templates/my-template.html'に変更しようとしましたが、うまくいきましたが、それは壊れやすいように見えます。 template-reading-serviceをより深いサブディレクトリに移動すると、そのパスは破損します。

したがって、アプリケーションのルートを基準にファイルを参照する適切な方法は何ですか?

答えて

15

ノードプロセスが実行されているディレクトリへの絶対パスを取得するには

var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8'); 
+2

__dirnameは実際には現在のスクリプト/モジュールの場所へのパスではありませんか?したがって、私の例では、 'template-reading-service'の中から実行するときです。js 'は__dirnameが'/services/'に解決されませんか? – user1438940

+0

@ user1438940 '/ server.js'にあるファイルの読み込みコードを実行したと思いました。試して "../templates/my-template.html" – InspiredJW

+0

いいえ、fs.getFileSyncを実行するコードは "template-reading-service.js"にあります。私は "../"を使いたくない。それは私の質問の全体のポイントです。私が "../"を使用し、その後 "template-reading-service.js"を "/ services /"ディレクトリから "/ services/templating /"に移動すると、すべてのコードが壊れます。あるいは、テンプレート・ディレクトリへのパスを、グローバル・コンフィギュレーションの設定として、ディレクトリ構造内の異なる場所にある20種類の他のサービスで使用する場合は、「../」は使用できません。どこからでも作業します – user1438940

26

を試してみてください、あなたはprocess.cwd()を使用することができます。あなたがモジュールとして/services/template-reading-service.jsを実装プロセスとして/server.jsを実行しているのでを想定し、その後、あなたは/サービス/テンプレート読書サービスから次の操作を行うことができますの.js:

var appRoot = process.cwd(), 
    templateContent = fs.readFileSync(appRoot + '/templates/my-template.html', 'utf8'); 

あなたがいることを起動するものは何でも持っている必要があります。その場合には、独立したプロセスとして/service/template-reading-service.jsを実行することができることは、動作しない場合処理するパスに処理するパスをプライマリアプリケーションとしますルート。たとえば、/server.jsが/service/template-reading-service.jsを別のプロセスとして起動した場合、/server.jsは、それ自身のprocess.cwd()を渡す必要があります。

+0

これは私にとってはうまくいくかもしれないと思ったが、私のすべての環境で働いています。私のプロダクション環境では、 'forever'を使用していますので、' process.cwd'は '/'を返します。 – user1438940

+0

これらの答えを見る将来の人たちのために、process.cwdは必ずしもあなたが探している答えではありません。たとえば、ウィンドウで、ノード・プロセスを.batファイルから実行すると、process.cwd()はノード・プロジェクトのルートではなく、.batファイルへのパスを戻します。 LinuxとMacにも同様のルールが適用されます。 – TKoL

12

受け入れられる答えが間違っています。ハードコーディングpath.join(__dirname, '../templates')は望ましくないことを正確に行い、service-XXX.jsファイルがサブ場所(指定された例としてservices/template)に移動するとメインアプリケーションを中断させます。

process.cwd()を使用すると、実行プロセスを開始したファイルのルートパスが返されます(例:/Myuser/myproject/server.js/Myuser/myproject/を返します)。

これは質問Determine project root from a running node.js applicationの複製です。

その質問では、__dirnameの回答が適切なホイッピングを得ました。 緑色のマーク、通行人に注意してください。

+2

私はapp-root-pathパッケージを使って恐ろしい時間を過ごしました。アプリを起動するには、ノードlib/my_app.jsまたはbin/my_app.jsの2つの方法がありました。 'path.join(__ dirname)'私は多くの時間を費やし、app-root-pathにパッチを適用してプラットフォーム間で動作するようにコードしました。最終的に 'path.join(__ dirname)'に切り替えました。まわりをシフトする。 – Ninjaxor

+1

これらの回答を見ている将来の人にとって:process.cwdは必ずしもあなたが探している答えではありません。たとえば、ウィンドウで、ノード・プロセスを.batファイルから実行すると、process.cwd()はノード・プロジェクトのルートではなく、.batファイルへのパスを戻します。 LinuxとMacにも同様のルールが適用されます。 – TKoL

関連する問題