在 Node 中,我如何优雅地处理需要模块读取其目录中的文件?
In Node, how do I elegantly handle requiring modules that read files in their directories?
例如,在我的项目目录中,我有:
|--bar.js
|--dir
|--foo.txt
|--readfile.js
readfile.js:
const fs = require('fs');
var foo = fs.readFileSync('foo.txt', 'utf8');
console.log(foo);
module.exports = {foo};
运行node readfile.js
,一切正常。
bar.js:
const readfile = require('./dir/readfile');
console.log(read.foo);
运行 node bar.js
, 我得到:
fs.js:663
return binding.open(pathModule.toNamespacedPath(路径),
^
Error: ENOENT: no such file or directory, open 'foo.txt'
at Object.fs.openSync (fs.js:663:18)
at Object.fs.readFileSync (fs.js:568:33)
at Object.<anonymous> (/Users/fterh/Documents/Projects/playground/dir/readfile.js:3:14)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Module.require (module.js:604:17)
at require (internal/module.js:11:18)
Fabians-MacBook-Pro:playground fterh$
我知道它与 bar.js 中的 require('./dir/readfile')
有关,因为 Node 然后尝试在与 "bar.js" 相同的目录中搜索 "foo.txt"。目前,我的解决方法是使用 path.dirname(__filename)
获取绝对路径,无论我是 运行 模块目录还是需要它,它都可以工作。我想知道是否有更优雅的做事方式。
require.resolve
在 readfile.js
中的使用如下:
const fs = require('fs');
let foo = fs.readFileSync(require.resolve('./foo.txt'), 'utf8');
console.log(foo);
module.exports = {foo};
注意:在 bar.js
的原始问题中,它可能打算写成:console.log(readfile.foo);
.
require.resolve
:
... return the resolved filename
使用 __dirname
构建您的路径,因为无论当前目录如何,该路径始终指向加载模块的目录。这是传递给模块的变量之一,因此它在每个模块的范围内都有一个唯一的值,它的目的正是您想要的(相对于模块目录执行文件操作)。
const fs = require('fs');
const path = require('path');
var foo = fs.readFileSync(path.join(__dirname, 'foo.txt'), 'utf8');
console.log(foo);
module.exports = {foo};
__dirname
here 的参考信息。
例如,在我的项目目录中,我有:
|--bar.js
|--dir
|--foo.txt
|--readfile.js
readfile.js:
const fs = require('fs');
var foo = fs.readFileSync('foo.txt', 'utf8');
console.log(foo);
module.exports = {foo};
运行node readfile.js
,一切正常。
bar.js:
const readfile = require('./dir/readfile');
console.log(read.foo);
运行 node bar.js
, 我得到:
fs.js:663 return binding.open(pathModule.toNamespacedPath(路径), ^
Error: ENOENT: no such file or directory, open 'foo.txt'
at Object.fs.openSync (fs.js:663:18)
at Object.fs.readFileSync (fs.js:568:33)
at Object.<anonymous> (/Users/fterh/Documents/Projects/playground/dir/readfile.js:3:14)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Module.require (module.js:604:17)
at require (internal/module.js:11:18)
Fabians-MacBook-Pro:playground fterh$
我知道它与 bar.js 中的 require('./dir/readfile')
有关,因为 Node 然后尝试在与 "bar.js" 相同的目录中搜索 "foo.txt"。目前,我的解决方法是使用 path.dirname(__filename)
获取绝对路径,无论我是 运行 模块目录还是需要它,它都可以工作。我想知道是否有更优雅的做事方式。
require.resolve
在 readfile.js
中的使用如下:
const fs = require('fs');
let foo = fs.readFileSync(require.resolve('./foo.txt'), 'utf8');
console.log(foo);
module.exports = {foo};
注意:在 bar.js
的原始问题中,它可能打算写成:console.log(readfile.foo);
.
require.resolve
:
... return the resolved filename
使用 __dirname
构建您的路径,因为无论当前目录如何,该路径始终指向加载模块的目录。这是传递给模块的变量之一,因此它在每个模块的范围内都有一个唯一的值,它的目的正是您想要的(相对于模块目录执行文件操作)。
const fs = require('fs');
const path = require('path');
var foo = fs.readFileSync(path.join(__dirname, 'foo.txt'), 'utf8');
console.log(foo);
module.exports = {foo};
__dirname
here 的参考信息。