正如我所看到的,Gjs imports
,默认情况下只加载/usr/share/gjs-1.0
和/usr/lib/gjs-1.0
。我想模块化应用程序,就像我们可以对 node 所做的那样,但我必须找到相对于脚本文件的模块。
我发现这是两种添加包含路径的方法:
-
gjs --include-path=my-modules my-script.js
-
GJS_PATH=my-modules gjs my-script.js
。但是两者都与当前目录相关,而不是与文件(不知不觉地)相关,并且它们需要在命令行上声明,这使得这变得不必要地复杂。
如何在 Gjs 代码中设置包含路径?(所以我可以相对于文件进行此操作)
或。。。还有另一种方法可以从任何地方导入文件,例如在 python 中?
(拜托,你不需要建议使用shellscript启动器来解决--include-path
和GJS_PATH
问题。这是显而易见的,但威力较小。如果我们没有更好的解决方案,我们就会生存下来。
设置或修改imports.searchPath
(这并不明显,因为它不会与for (x in imports)print(x)
一起显示)。 所以这个:
imports.searchPath.unshift('.');
var foo = imports.foo;
导入文件"foo.js"作为foo
对象。
这与Seed兼容,尽管imports
知道它有一个searchPath
。
(这个答案的早期版本基本上不那么准确,更具煽动性。对不起)。
正如 Douglas 所说,您确实需要修改imports.searchPath
以包含您的库位置。使用 .
很简单,但取决于始终从同一目录位置运行的文件。不幸的是,找到当前正在执行的脚本的目录是一个巨大的黑客。以下是 Gnome Shell 如何为扩展 API 执行此操作
我已将其改编为以下功能以供一般使用:
const Gio = imports.gi.Gio;
function getCurrentFile() {
let stack = (new Error()).stack;
// Assuming we're importing this directly from an extension (and we shouldn't
// ever not be), its UUID should be directly in the path here.
let stackLine = stack.split('n')[1];
if (!stackLine)
throw new Error('Could not find current file');
// The stack line is like:
// init([object Object])@/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
//
// In the case that we're importing from
// module scope, the first field is blank:
// @/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
let match = new RegExp('@(.+):\d+').exec(stackLine);
if (!match)
throw new Error('Could not find current file');
let path = match[1];
let file = Gio.File.new_for_path(path);
return [file.get_path(), file.get_parent().get_path(), file.get_basename()];
}
以下是定义getCurrentFile
函数后,从入口点文件app.js
如何使用它:
let file_info = getCurrentFile();
// define library location relative to entry point file
const LIB_PATH = file_info[1] + '/lib';
// then add it to the imports search path
imports.searchPath.unshift(LIB_PATH);
Wee!现在导入我们的库非常简单:
// import your app libraries (if they were in lib/app_name)
const Core = imports.app_name.core;