8

As i could see, the Gjs imports, loads only /usr/share/gjs-1.0 and /usr/lib/gjs-1.0 by default. I want to modularize an application, like we can do with node, but i must find modules relative to the script file.

I found this two ways to add include paths:

  1. gjs --include-path=my-modules my-script.js
  2. GJS_PATH=my-modules gjs my-script.js

...but both are related to the current directory, not to the file (obliviously), and they needed to be declared on the command line, making this unnecessarily complex.

How can i set a including path in the Gjs code? (So i can make this relative to the file)

Or... There is another way to import files from anywhere, like in python?

(Please, you don't need to propose to use a shellscript launcher to solve the --include-path and GJS_PATH problem. That is obvious, but less powerful. If we do not have a better solution, we survive with that.)

4

2 回答 2

12

您需要设置或修改imports.searchPath(这并不明显,因为它没有显示for (x in imports)print(x))。所以这:

imports.searchPath.unshift('.');
var foo = imports.foo;

导入文件“foo.js”作为foo对象。

这与Seed兼容,尽管imports知道它有一个searchPath.

(这个答案的早期版本的准确性大大降低,而且更具煽动性。对不起)。

于 2012-05-29T11:25:20.923 回答
10

正如道格拉斯所说,您确实需要修改imports.searchPath以包含您的库位置。使用.很简单,但取决于始终从同一目录位置运行的文件。不幸的是,找到当前执行脚本的目录是一个巨大的 hack。下面是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()];
}

app.js在定义getCurrentFile函数之后,您可以从入口点文件中使用它:

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);

哇!现在导入我们的库非常简单:

// import your app libraries (if they were in lib/app_name)
const Core = imports.app_name.core;
于 2012-12-29T03:02:53.253 回答