【问题标题】:Find absolute base path of the project directory查找项目目录的绝对基本路径
【发布时间】:2013-08-25 02:05:34
【问题描述】:

到目前为止,我们可以使用以下代码 sn-p 获取文件的绝对路径,以便稍后以 readStream 的形式打开:

var base = path.resolve('.');
var file = base + '/data/test.csv';

fs.createReadStream(file)

从 Meteor 0.6.5 开始,基本路径指向 .meteor/local/build/programs/...

还有 Assets API,它不能给我们返回路径,只能给我们读取的文档。但我们需要一个流来处理一些更大的数据文件?

【问题讨论】:

  • 嗨 Loomi,您能否澄清一下您的问题 - 新的基本路径造成的问题是什么?
  • @stephan-tual 嗨 Stephan,由于 Meteor 的变化,如果我理解正确,文件会在运行前复制到构建目录。这意味着不可能使用 nodejs 内部手动访问文件。我正在寻找一种方法来引用项目目录中稳定的文件。如果我没看错,Assets API 就会这样做。但它直接传递文件。另一方面,我只需要获取可以打开文件表单的路径,例如/private/something.csv 比 fs.createReadStream.
  • 嗨 Loomi,你看过这个包吗:atmosphere.meteor.com/package/fs
  • 知道基本路径更改为 .meteor/local/build/programs 很有用。帮助我找到了一个我盲目编写但没有完整路径的文件:-)
  • 有一个feature request 用于获取资产的绝对路径。

标签: node.js meteor fs


【解决方案1】:

你可以通过

获得项目的基本根路径
process.env.PWD

【讨论】:

    【解决方案2】:

    从 1.3 版开始,documented 函数

    Assets.absoluteFilePath(assetPath)

    似乎是可靠地获取项目路径的最佳方式。

    Meteor Github

    【讨论】:

    • 什么是assetPath?即使我没有任何资产,我也可以使用它吗?
    • 这个函数返回一个资产的路径。这最终是一个干净的版本,可以找到您喜欢在 Meteor 应用程序中使用的文件的路径。如果您需要绝对路径而不需要解决资产,我猜您创建了一个虚拟资产并剥离了不必要的部分。
    • 嗯,这很好,但最初的问题是关于项目基本路径,而不是资产路径。所以实际上这个答案是错误的。这不应该是公认的答案。
    • 有点正确,但我想大多数人需要基本路径来访问与应用程序相关的一些特定文件。所以我认为这是长期最稳健的方法。 (另请参阅问题本身的 cmets。)
    【解决方案3】:

    从 Meteor 1.2.1 开始,这对我有用:

    var absoluteBasePath = path.resolve('../../../../../.');
    

    使用split得到同样的结果:

    var absoluteBasePath = path.resolve('.').split(path.sep + '.meteor')[0];
    

    使用process.cwd()

    var absoluteBasePath = path.resolve(process.cwd(), '../../../../../');
    var absoluteBasePath = path.resolve(process.cwd()).split(path.sep + '.meteor')[0];
    

    【讨论】:

    • 然后从 Meteor 1.2.1x 开始,如果他们改变约定,它可能会再次中断。使用该系统更安全。
    • 是的,当然。你打算怎么做这样的系统?您能提供替代解决方案吗?
    • 除非您的用例不太常见,否则我认为 process.env.PWD 的公认答案应该可以解决问题。但是,如果您从与基本目录不同的目录运行流星(如果这甚至是任何人都会做的事情),那么您可能需要变得更有趣。
    • process.env.PWD 在 Windows 上不起作用。并且从不同的目录调用meteor也是可能的。那么你对如何解决通用案例有什么想法吗?
    • 这很好。它应该在任何地方都有效。这可能是一个愚蠢的想法,但您可以使用该线程问题提供的“解决方案”在 Windows 中获得 PWD 等效项:github.com/nodejs/node-v0.x-archive/issues/2305 - 问题在于它很难看。但是在这种情况下,您可以通过在流星启动时调用该函数并将其添加到 Meteor.settings 来使用 PWD。不漂亮,但可能比在目录结构再次更改时必须在一年内搜索 40 个 path.resolve('../../../../../../.') 实例更好。
    【解决方案4】:

    现在找到项目根目录的另一种方法是:

    var base = process.env.PWD
    

    请注意,这与process.cwd() 不同。相反,它是您运行meteor 命令的目录,这通常是您要查找的目录。另请注意,从已部署的 bundle 运行您的应用时,这可能不会很有帮助。

    【讨论】:

    • 我不知道。我只是在当前版本中自己发现了这一点。
    • 它不是 Node 应用程序根路径。仅目录路径,取决于您执行此代码的位置。
    • @anshuman:你能解释一下“目录路径”是什么意思吗?另外,当你说它取决于它在哪里执行时,你在考虑哪些地方?显然,这不是针对客户的,如果您是这样想的话。
    • @ChristianFritz ,操作问题是找到“项目”目录的绝对基本路径,而不是当前工作目录。您的解决方案将仅提供当前工作目录的路径。因为 process.env.PWD 只不过是为当前工作目录设置的 PWD 环境变量(至少在 linux 上。但不确定 Windows。)
    • @ChristianFritz 谢谢你的建议。然而,这似乎只在本地运行我的 Meteor 应用程序时才有效。部署在 *.meteor.com 的捆绑应用似乎不接受这种方法。有什么想法吗?
    【解决方案5】:

    嘿,你不需要像上面的答案那样硬编码......看看This package

    安装后,您可以通过Meteor.rootPath访问您的流星的根路径

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 它不是一个仅链接的答案,我告诉他如何使用该包访问 root.path...
    • 从 Meteor 1.2.1 起不适用于 Windows:github.com/VeliovGroup/Meteor-root/issues/3
    • 在 ostrio:meteor-root 1.0.3 修复
    【解决方案6】:

    对于 Meteor 0.8.3,

    __meteor_bootstrap__.serverDir 在服务器模式下运行时给出工作目录。

    例子

    if (Meteor.isServer) {
       console.log(__meteor_bootstrap__.serverDir);
    }
    

    【讨论】:

    • 在 Meteor 1.0 中它说 __meteor_bootstrap__ is not defined
    • 从 Windows 上的 Meteor 1.2.1 开始,__meteor_bootstrap__ 被定义为等于 path.resolve('.')process.cwd()
    【解决方案7】:

    我在更新到 0.6.5 时遇到了同样的困境。

    我目前正在做的是得到这样的路径:

    var meteor_root = Npm.require('fs').realpathSync( process.cwd() + '/../' );
    

    这会返回开发模式

    /my/application/.meteor/local/build/programs
    

    在捆绑模式下

    /my/application/build/app/programs
    

    所以我从这里进入我的应用程序的“根”路径,如下所示:

    var application_root = Npm.require('fs').realpathSync( meteor_root + '/../' );
    
    // if running on dev mode
    if( Npm.require('path').basename( Npm.require('fs').realpathSync( meteor_root + '/../../../' ) ) == '.meteor' ){
        application_root =  Npm.require('fs').realpathSync( meteor_root + '/../../../../' );
    }
    

    唯一会失败的情况是,如果您碰巧将应用程序的文件夹命名为“.meteor”,但这是一种极端情况。

    相对于你可以访问任何你需要的东西。

    此外,您还可以直接访问流星捆绑器创建的资产文件夹:

    var assets_folder = meteor_root + '/server/assets/' + Npm.require('path').basename( application_root );
    

    这可能是暂时的,因为我希望最终会添加更好的文件/路径交互 API。

    希望有帮助

    【讨论】:

    • 不错的解决方案,但绝对是框架将来需要处理的问题。我们在同一页上吗?
    • @loomi 是的,绝对是。我认为他们需要比“获取文件内容”更好的 API 来使其成为一个更可用的框架。好消息是总有合理的解决方法;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 2013-09-14
    • 2010-11-21
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多