【问题标题】:Determine command line working directory when running node bin script运行节点 bin 脚本时确定命令行工作目录
【发布时间】:2012-08-27 15:17:21
【问题描述】:

我正在创建一个节点命令行界面。全局安装,使用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 中的命令行目录。

【问题讨论】:

    标签: node.js command-line npm


    【解决方案1】:
    • process.cwd() 返回执行命令的目录(不是节点包的目录),如果它没有被应用程序内部的 'process.chdir' 更改。
    • __filename 返回文件所在文件的绝对路径。
    • __dirname 返回__filename 目录的绝对路径。

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

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

    而不是

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

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

    【讨论】:

    • process.chdir()之后,有没有办法拿到原版?
    • @reergymerej 您可能希望在执行 chdir() 之前先存储 cwd(例如,var originalCwd = process.cwd(); 然后执行您的 process.chdir(),然后您可以返回原始数据)。
    • ../lib/test 便携吗?
    • 没有。它不是一个可移植的解决方案,因为 Windows 使用反斜杠。因此,如果您尝试在 Windows 中运行它,它将无法正常工作。
    • 其实对于 NodeJS 这都是一样的。即使在 Windows 上,您也可以方便地以 Unix 方式要求相对路径。所以../lib/test 是可移植的,而Windows 对应的..\lib\test 不是...
    【解决方案2】:

    或者,如果您只想获取当前 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】:

      当前工作目录

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

      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的目录
      • 注意,$INIT_CWD 仅适用于 Linux。对于 Windows,您必须使用 %INIT_CWD%。我认为这个问题可以通过使用 npmjs.com/package/cross-env 来解决,但我自己没有尝试过
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        这对我有用:

        console.log(process.mainModule.filename);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-07
          • 2011-06-11
          • 2022-08-15
          • 2019-12-15
          • 1970-01-01
          • 1970-01-01
          • 2021-06-17
          • 1970-01-01
          相关资源
          最近更新 更多