2012-04-10 13 views
6

Como pude ver, el Gjs imports, carga solo /usr/share/gjs-1.0 y /usr/lib/gjs-1.0 de forma predeterminada. Quiero modularizar una aplicación, como podemos hacer con node, pero debo encontrar módulos relativos al archivo de script.¿Cómo establecer una ruta de acceso incluida en el código de Gjs?

He encontrado estas dos formas de añadir incluyen caminos:

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

... pero ambos están relacionados con el directorio actual, no con el archivo (olvidadizamente), y tenían que declararse en la línea de comandos, lo que hacía innecesariamente complejo.

¿Cómo puedo establecer una ruta de acceso incluida en el código de Gjs? (Así que puedo hacer esto en relación con el archivo)

O ... ¿Hay otra forma de importar archivos desde cualquier lugar, como en python?

(Por favor, no es necesario proponer utilizar un lanzador shellscript para resolver el problema --include-path y GJS_PATH. Eso es obvio, pero menos potente. Si no tenemos una mejor solución, sobrevivimos con eso.)

Respuesta

8

Debe establecer o modificar imports.searchPath (que no es obvio porque no aparece con for (x in imports)print(x)). Así que esto:

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

importa los archivos “foo.js” como el objeto foo.

Esto es compatible con Seed, aunque existe imports sabe que tiene searchPath.

(Las versiones anteriores de esta respuesta eran sustancialmente menos precisas y más inflamatorias.

5

Como dice Douglas, debe modificar imports.searchPath para incluir la ubicación de su biblioteca. El uso de . es simple, pero depende de que los archivos se ejecuten siempre desde la misma ubicación de directorio. Lamentablemente, encontrar el directorio de la secuencia de comandos que se está ejecutando actualmente es un gran truco. Así es como Gnome Shell does it for the extensions API

he adaptado esto en la siguiente función para uso general:

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()]; 
} 

Así es como es posible utilizarlo desde su archivo de punto de entrada app.js, después de definir la función 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); 

¡Wee! Ahora importar nuestras bibliotecas es súper fácil:

// import your app libraries (if they were in lib/app_name) 
const Core = imports.app_name.core; 
Cuestiones relacionadas