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


120

我正在创建节点命令行界面。它是全局安装的,并使用bin文件执行。

我计划在正在处理的文件的根目录下打开一个命令窗口,然后运行命令,但是由于process.cwd()返回节点包的目录,我无法确定当前的工作目录。最初,我假定由于代码是使用批处理文件作为包装器执行的(这是bin文件可以在开始时没有节点的情况下执行的方式),所以这是不可能的,但是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中的命令行目录。

Answers:


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

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

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

代替

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

require(lib + '/test');

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


2
之后process.chdir(),有什么方法可以获取原件?
reergymerej 2015年

@reergymerej您可能需要先存储cwd,var originalCwd = process.cwd();然后再执行chdir()(例如,然后执行,然后process.chdir()可以返回到原始位置)。
旋转

../lib/test便携式的吗?
塞巴斯蒂安

不能。这不是便携式解决方案,因为Windows使用反斜杠。因此,如果您尝试在Windows中运行它,将无法正常工作。
zachdyer

1
实际上,对于NodeJS来说都是一样的。即使在Windows上,您也可以方便地以Unix方式要求相对路径。因此../lib/test具有可移植性,而Windows ..\lib\test则不具有可移植性……
Christian Ulbrich

47

当前工作目录

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

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"
}

process.env.INIT_CWD返回package.json
vaughan

2
请注意,$ INIT_CWD仅在Linux上有效。对于Windows,您必须使用%INIT_CWD%。我认为可以使用npmjs.com/package/cross-env解决此问题,但我自己还没有尝试过
Stephanie

3

另外,如果您只想获取当前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);

3

path.resolve('.')也是一种可靠且干净的选择,因为我们几乎总是require('path')。它将为您提供调用目录的绝对路径。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.