【问题标题】:How to comfortably work with paths that are relative to the working directory in Deno?如何舒适地使用与 Deno 中的工作目录相关的路径?
【发布时间】:2021-07-22 16:05:41
【问题描述】:

我最初的动机是在 Ubuntu 上从 Crontab 运行 Deno 脚本。

首先我不知道路径是相对于工作目录的,而不是相对于执行模块的。

我的脚本正在读取文件并将其写入磁盘,所以出现了类似的错误

error: Uncaught NotFound: No such file or directory (os error 2)

有人指出这个问题可以用import.meta.url解决。

我修改了从import.meta.url 解析它的路径,这个解决方案在读/写操作上运行良好。

但是我遇到了.env 文件的另一个问题。 令我惊讶的是,即使是 dotenv 模块也使用相对于工作目录的路径。

dotenv模块可以选择用config({path:___})指定路径,但是我觉得覆盖默认位置太多了。

最终,在 crontab 中运行脚本之前将工作目录更改为脚本的根目录是一个更简单的解决方案。

* * * * * cd ____; deno run ___

但我仍然怀疑这是否是最有效的方法。

在这种情况下更改目录有什么更好的方法吗?

运行 deno 时最好有一个模式,这将使路径相对于执行模块,不包括使用 URL 导入的模块。

【问题讨论】:

    标签: deno


    【解决方案1】:

    我认为您正在寻找Deno.mainModule,它是对您传递给deno 的入口点模块的文件URL 的引用。您可以将它与deno.land/std/path 模块一起使用以获取程序入口点的目录,然后使用Deno.chdir() 更改当前工作目录,以便所有相对路径(隐式相对于Deno.cwd())相对于该目录。

    /repo/relative-path.ts:

    import * as path from 'https://deno.land/std@0.102.0/path/mod.ts';
    export {path};
    
    export const mainModuleDir = path.dirname(path.fromFileUrl(Deno.mainModule));
    

    /repo/main.ts:

    import {mainModuleDir, path} from './relative-path.ts';
    
    Deno.chdir(mainModuleDir);
    
    const entrypointRelativePath = path.resolve('hello', 'world.json');
    console.log(entrypointRelativePath);
    

    然后,运行您的脚本:

    $ cd /different/unrelated/path
    $ deno run --allow-read /repo/main.ts
    /repo/hello/world.json
    

    您可以使用mainModuleDir 作为您需要的任何入口点相关路径的基础。

    【讨论】:

    • 感谢您的回复!我已经检查了您的解决方案,但它不适合我的问题。正如您所建议的,我们可以从Deno.mainModule 找到正确的路径。但要使其工作,我们需要修改每个路径相关的参考。例如,如果我需要加载.env,我会写import { config } from "https://deno.land/x/dotenv/mod.ts"; console.log(config({ path:path.join(mainModuleDir,".env") })) 但是我正在寻找一个解决方案,当您不需要修改每个路径相关的引用时。
    • @Olek 我已经更新了我的答案。它现在回答你的问题了吗?
    • Deno.chdir() 适用于一个文件。也许我要求太多了。但是有没有办法自动实施您在每个 .ts 文件中建议的解决方案?我想编辑 Deno 源代码就可以了,但我不知道 Rust,每次更新后都应该重新实现更改。
    • ? “自动”行为通常是 Deno 中的反模式(因此代码更容易推理)。我认为您想要的唯一方法是 (1) 编辑 Deno 源并重新编译或 (2) 使用 Deno.run 创建脚本执行框架,在 RunOptions 中传递入口点和所需的 CWD,所以子进程实际运行您的脚本。
    • 我同意你的看法。对我来说,编辑 Deno 源代码不是一种选择。编写一个包装函数来运行 Deno 脚本更加现实。但是我不明白为什么 Deno 开发团队没有实现这样的功能。它不会损害 Deno 原则。添加一个标志,例如“--relative”来标记你想从任何路径运行脚本,将是一个很大的好处。
    猜你喜欢
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多