我最初的动机是在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.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
作为所需的任何入口点相对路径的基础。