NodeJS 运行节点bin脚本时确定命令行工作目录

a0x5cqrl  于 2023-01-08  发布在  Node.js
关注(0)|答案(6)|浏览(209)

我正在创建一个节点命令行界面。它是全局安装的,使用bin文件来执行。
我计划在我正在处理的文件的根目录下打开一个命令窗口,然后运行该命令,但是我无法确定当前的工作目录,因为process.cwd()返回的是节点包的目录。(这就是bin文件如何在开始时没有节点的情况下执行)那么这是不可能的,但coffee-script设法做到了。我看了看coffee-script的源代码,但无法理解(经验不足)。
要自己测试它,请使用此package.json文件创建一个包:

{
  "name": "test-package",
  "version": "1.0.0",
  "bin": {
    "test-package":  "./bin/test-package"
  },
  "main": "/lib/test"
}

bin中的此测试包文件:

#!/usr/bin/env node

var path = require('path');
var fs   = require('fs');
var lib  = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require(lib + '/test');

有人能解释一下吗。
然后尝试获取lib/test中的命令行目录。

chhkpiq4

chhkpiq41#

  • process.cwd()返回执行命令的目录(不是节点包的目录),如果应用程序内部的“process.chdir”未更改该目录。
  • __filename返回文件的绝对路径。
  • __dirname返回__filename目录的绝对路径。

如果需要从模块目录加载文件,则需要使用相对路径。

require('../lib/test');

代替

var lib  = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require(lib + '/test');

它总是相对于它调用的文件,而不依赖于当前的工作目录。

goucqfw6

goucqfw62#

当前工作目录

要获取当前工作目录,可以用途:

process.cwd()

但是,请注意,有些脚本(特别是gulp)会使用process.chdir()更改当前工作目录。

节点模块路径

您可以使用以下命令获取当前模块的路径:

  • __filename
  • __dirname

原始目录(启动命令的位置)

如果从命令行运行脚本,并且需要运行脚本的原始目录,无论脚本当前在哪个目录中运行,都可以用途:

process.env.INIT_CWD

使用NPM脚本时的原始目录

有时候需要在当前目录下运行NPM脚本,而不是在项目的根目录下运行。
此变量在npm包脚本中可用,如下所示:

$INIT_CWD.

您必须运行最新版本的NPM。如果此变量不可用,请确保NPM是最新的。
这将允许您访问package.json中的当前路径,例如:

scripts: {
  "customScript": "gulp customScript --path $INIT_CWD"
}
w8f9ii69

w8f9ii693#

path.resolve('.')也是一个可靠和干净的选项,因为我们几乎总是require('path')。它会给予你从哪里调用它的目录的绝对路径。

brvekthn

brvekthn4#

或者,如果您只想获取当前NodeJS脚本的当前目录,您可以尝试类似下面的简单操作。注意,这在Node CLI本身中不起作用:

var fs = require('fs'),
    path = require('path');

var dirString = path.dirname(fs.realpathSync(__filename));

// output example: "/Users/jb/workspace/abtest"
console.log('directory to start walking...', dirString);
umuewwlo

umuewwlo5#

以下是对我有效的方法:

console.log(process.mainModule.filename);
83qze16e

83qze16e6#

使用ES模块时的警告

根据ECMAScript模块文档:
CommonJS变量__filename__dirname在ES模块中不可用。
相反,可以通过import.meta.url复制用例。
因此,根据why is __dirname not defined in node?,您可以执行以下操作:

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

相关问题