fsを使用して、上のディレクトリのファイルを取得しようとするとError: ENOENT: no such file or directory, open が出て、喚いていたが解決したので残しておく。
既知の事実と言ってはいけない。
#ファイル内容
先に記しておくが、後の説明を読みながら解釈することを勧める。
test(親ディレクトリ)
├── src
│ └── fileManeger.js
├── config ←(ここに出力)
│
└── main.js
const fs = require('fs'); //nodeモジュール読みこみ
const fileManegerClass = require('./src/fileManeger.js') //クラスファイル読みこみ
const fileManeger = new fileManegerClass(); //インスタンス化
const content = {"name" : "taro" , "age" : 30};
//fsを引数から受け取る 相対パスをmain.jsがあるディレクトリからに
fileManeger.write1(content, fs);
//fsをメソッド内でインポート 相対パスをmain.jsがあるディレクトリからに
fileManeger.write2(content);
//fsを引数から受け取る 相対パスをfileManeger.jsがあるディレクトリからに
fileManeger.write3(content, fs);
//fsをメソッド内でインポート 相対パスをfileManeger.jsがあるディレクトリからに
fileManeger.write4(content);
class fileManeger {
//fsを引数から受け取る 相対パスをmain.jsがあるディレクトリからに
async write1 (content,fs){
try{
fs.writeFileSync('./config/write-1.json', JSON.stringify(content, null, "\t"),'utf8');
console.log(`write1 complete`);
}catch(e){
console.log(`write1 fail\n${e}\n-------------------------------\n`);
};
};
//fsをメソッド内でインポート 相対パスをmain.jsがあるディレクトリからに
async write2 (content) {
const fs = require('fs');
try{
fs.writeFileSync('./config/write-2.json', JSON.stringify(content, null, "\t"),'utf8');
console.log(`write2 complete`);
}catch(e){
console.log(`write2 fail\n${e}\n-------------------------------\n`);
};
};
//fsを引数から受け取る 相対パスをfileManeger.jsがあるディレクトリからに
async write3 (content,fs) {
try{
fs.writeFileSync('../config/write-3.json', JSON.stringify(content, null, "\t"),'utf8');
console.log(`write3 complete`);
}catch(e){
console.log(`write3 fail\n${e}\n-------------------------------\n`);
};
};
//fsをメソッド内でインポート 相対パスをfileManeger.jsがあるディレクトリからに
async write4 (content) {
const fs = require('fs');
try{
fs.writeFileSync('../config/write-4.json', JSON.stringify(content, null, "\t"),'utf8');
console.log(`write4 complete`);
}catch(e){
console.log(`write4 fail\n${e}\n-------------------------------\n`);
};
};
};
module.exports = fileManeger; //クラス出力
やりたいこと
main.jsから./src/fileManeger.js
(クラス)を読み込み、configディレクトリ内にファイルを出力する。
#はまった理由
結論から言うと、fsのパスの指定の仕方が悪かった。私は最初、fileManeger.jsでfsは呼び出されるのだからパスはそのファイルからたどるのだろうと勝手に推測して../config/write.json
と指定していた。
しかしながら、fsはパスを作業ディレクトリからたどる。ここでいう作業ディレクトリとはnodeで実行したファイルがあるディレクトリのこと、つまりtestディレクトリである。
ということは私が指定したディレクトリはtestディレクトリの上層にあることになってしまっていたのだ。
│
├──config(???? 幻のディレクトリ)
│
└──test(ここから ../config/write.json)
├── src
│ └── fileManeger.js
├── config ←(ここを指定したはずが...)
│
└── main.js
#試してみた
testディレクトリでmain.jsを実行する。
比較のため、fsモジュールの読み込み箇所と出力ファイル名、パスを変えている。
一応、モジュールをインポートする場所は関係ないことを示すために4つのパターンを用意した。
メソッド名 | パス | モジュールの読み込み | 出力ファイル名 |
---|---|---|---|
write1 | ./config/write-1.json | 引数から | write-1.json |
write2 | ./config/write-2.json | メソッド内で | write-2.json |
write3 | ../config/write-3.json | 引数から | write-3.json |
write4 | ../config/write-4.json | メソッド内で | write-4.json |
実行結果
./config/write-〇.json
のパスであるwrite1メソッドとwrite2メソッドは成功している。
一方、../config/write-〇.json
のパスであるwrite3メソッドとwrite4メソッドは読み込めないとエラーが出ている。
ファイルもwrite-1.json
とwrite-2.json
のみ出力されている。
#結論
以上のことから、fsのファイルパスの起点はnode.jsで実行しているファイルがあるディレクトリであることがわかった。
よって、fsを使用したコードのエラーでError: ENOENT: no such file or directory, openが出た際は、ファイルのパスがnode.jsで実行しているファイルがあるディレクトリからの相対パスになっているか確認しよう。
#参考
公式ドキュメントにファイルパスの話が出ているのでその部分のリンクを記載しておく。
Node.js v14.13.1 Documentation
検証に使用したソースコード
github huda0209/qiita_fs-sample