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:
gjs --include-path=my-modules my-script.js
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.)
As Douglas says, you do need to modify imports.searchPath
to include your library location. Using .
is simple, but depends on the files always being run from the same directory location. Unfortunately finding the directory of the currently executing script is a huge hack. Here's how Gnome Shell does it for the extensions API
I've adapted this into the following function for general use:
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/[email protected]/prefs.js:8
//
// In the case that we're importing from
// module scope, the first field is blank:
// @/home/user/data/gnome-shell/extensions/[email protected]/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()];
}
Here's how you might use it from your entry point file app.js
, after defining the getCurrentFile
function:
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! now importing our libraries is super-easy:
// import your app libraries (if they were in lib/app_name)
const Core = imports.app_name.core;
You need to set or modify imports.searchPath
(which is not obvious because it doesn't show up with for (x in imports)print(x)
). So this:
imports.searchPath.unshift('.');
var foo = imports.foo;
imports the file “foo.js” as the foo
object.
This is compatible with Seed, although there imports
knows it has a searchPath
.
(Earlier versions of this answer were substantially less accurate and more inflammatory. Sorry).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With